Cod sursa(job #1932837)

Utilizator borcanirobertBorcani Robert borcanirobert Data 20 martie 2017 10:14:13
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <queue>
using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

const int MAX = 1005;
const int Inf = 0x3f3f3f3f;
const int di[] = { -1, 0, 1, 0 };
const int dj[] = { 0, 1, 0, -1 };
int N, M;
int a[MAX][MAX];
string s;
int d[MAX][MAX];
bool c[MAX][MAX];
queue< pair<int, int> > Q;
int x1, y1, x2, y2;
int x, y, dist;
int maxim;

void Read();
void Dragoni();
void Solve();
bool OK( int i, int j );
void Fill();

int main()
{
    Read();
    Dragoni();
    Solve();

    fin.close();
    fout.close();
    return 0;
}

void Read()
{
    fin >> N >> M;
    memset(d, Inf, sizeof(d));
    for ( int i = 1; i <= N; ++i )
    {
        fin >> s;
        for ( int j = 0; j < M; ++j )
        {
            if ( s[j] == '*' )
                a[i][j + 1] = -1;
            if ( s[j] == 'D' )
            {
                d[i][j + 1] = 0;
                Q.push({i, j + 1});
            }
            if ( s[j] == 'I' )
                x1 = i, y1 = j + 1;
            if ( s[j] == 'O' )
                x2 = i, y2 = j + 1;
        }
    }
}

void Dragoni()
{
    while ( !Q.empty() )
    {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();

        c[i][j] = true;

        for ( int k = 0; k < 4; ++k )
        {
            int iv = i + di[k];
            int jv = j + dj[k];

            if ( OK(iv, jv) && a[iv][jv] != -1 && !c[iv][jv] && d[iv][jv] > d[i][j] + 1 )
            {
                d[iv][jv] = d[i][j] + 1;
                Q.push({iv, jv});
            }
        }
    }

    for ( int i = 1; i <= N; ++i )
    {
        for ( int j = 1; j <= M; ++j )
            maxim = max( maxim, d[i][j] );
    }
}

void Solve()
{
    int st = 0, dr = maxim, mij, r = -1;

    while ( st <= dr )
    {
        mij = ( st + dr ) / 2;
        memset(c, 0, sizeof(c));
        x = x1, y = y1, dist = mij;
        Fill();

        if ( c[x2][y2] )
        {
            r = mij;
            st = mij + 1;
        }
        else
            dr = mij - 1;
    }

    fout << r << '\n';
}

bool OK( int i, int j )
{
    return i >= 1 && i <= N && j >= 1 && j <= M;
}

void Fill()
{
    if ( !OK(x, y) || a[x][y] == -1 || c[x][y] == 1 )
        return;
    if ( d[x][y] < dist )
        return;
    c[x][y] = 1;

    x++; Fill(); x--;
    x--; Fill(); x++;
    y++; Fill(); y--;
    y--; Fill(); y++;
}