Cod sursa(job #1095673)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 31 ianuarie 2014 17:33:23
Problema Barbar Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include<fstream>

using namespace std;

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

struct poz { int l, c; } Q[1000001];
poz exit, intr;
poz q[1000001];

const int INF = 1 << 30;
int n, m;
int d[1002][1002];
int dl[4] = { -1, 0, 0, 1 };
int dc[4] = { 0, -1, 1, 0 };

bool check( int dist ) {
    int first, last;
    bool w[1002][1002];

    for( int i = 0; i <= n + 1; ++ i )
        for( int j = 0; j <= m + 1; ++ j )
            w[i][j] = 0;

    q[0] = intr;
    first = last = 0;
    while ( first <= last ) {
        poz acum = q[first++];
        for( int k = 0; k < 4; ++ k ) {
            poz v;
            v.l = acum.l + dl[k];
            v.c = acum.c + dc[k];
            if ( !w[v.l][v.c] && dist <= d[v.l][v.c] ) {
                q[++last] = v;
                w[v.l][v.c] = 1;
            }
        }
    }
    return w[exit.l][exit.c];
}

int main()
{
    char c;
    fin>>n>>m;
    fin.get();
    for( int i = 0; i <= m + 1; ++ i )
        d[0][i] = d[n+1][i] = -1;
    for( int i = 0; i <= n + 1; ++ i )
        d[i][0] = d[i][m+1] = -1;

    int first, last;
    first = 0; last = -1;
    for ( int i = 1; i <= n; ++ i ) {
        for ( int j = 1; j <= m; ++ j ) {
            fin.get( c );
            if ( c == '*' )
                d[i][j] = -1;
            else if ( c == 'I' ) {
                d[i][j] = INF;
                intr.l = i;
                intr.c = j;
            } else if ( c == 'O' ) {
                exit.l = i;
                exit.c = j;
                d[i][j] = INF;
            } else if ( c == 'D' ) {
                Q[++last].l = i;
                Q[last].c = j;
                d[i][j] = 0;
            } else
                d[i][j] = INF;
        }
        fin.get();
    }

    while ( first <= last ) {
        poz acum;
        acum = Q[first++];
        for ( int k = 0; k < 4; ++ k ) {
            poz v;
            v.l = acum.l + dl[k];
            v.c = acum.c + dc[k];
            if ( d[v.l][v.c] > d[acum.l][acum.c] + 1 ) {
                d[v.l][v.c] = d[acum.l][acum.c] + 1;
                Q[++last] = v;
            }
        }
    }

    int n2, sol, lim;
    lim = d[exit.l][exit.c]<d[intr.l][intr.c]?d[exit.l][exit.c]:d[intr.l][intr.c];
    for( n2 = 1; n2 * 2 <= lim; n2 *= 2 ) {
    }

    sol = 0;
    for( int pas = n2; pas > 0; pas /= 2 )
        if ( sol + pas <= lim && check( sol+pas ))
            sol += pas;
    if ( sol == 0 )
        fout<<"-1\n";
    else
        fout<<sol<<'\n';
    fin.close();
    fout.close();
    return 0;
}