Cod sursa(job #396798)

Utilizator ssergiussSergiu-Ioan Ungur ssergiuss Data 15 februarie 2010 21:39:28
Problema Barbar Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <algorithm>
#include <queue>
using namespace std;

#define DIM 1<<10
#define INF 0x3f3f3f3f

int N, M, XS, YS, XD, YD, XXX;
int aux[ DIM ][ DIM ], harta[ DIM ][ DIM ], dragon[ DIM ][ DIM ];
const int dx[ 4 ] = { 0, 0, -1, 1 }, dy[ 4 ] = { -1, 1, 0, 0 };
queue < pair <int, int> > q;

inline int check( const int &distanta ) {

    int i, x, y;

    memset( aux, 0, sizeof( aux ) );
    for( q.push( make_pair( XS, YS ) ); !q.empty(); q.pop() ) {

        x = q.front().first;
        y = q.front().second;
        for( i = 0; i < 4; ++i )
            if( !aux[ x + dx[ i ] ][ y + dy[ i ] ] && dragon[ x + dx[ i ] ][ y + dy[ i ] ] <= distanta ) {

                aux[ x + dx[ i ] ][ y + dy[ i ] ] = 1;
                q.push( make_pair( x + dx[ i ], y + dy[ i ] ) );
            }
    }
    if( aux[ XD ][ YD ] )
        return 1;

    return 0;
}

void bf_dragon() {

    int i, x, y;

    for( ; !q.empty(); q.pop() ) {

        x = q.front().first;
        y = q.front().second;
        for( i = 0; i < 4; ++i )
            if( !dragon[ x + dx[ i ] ][ y + dy[ i ] ] ) {

                dragon[ x + dx[ i ] ][ y + dy[ i ] ] = dragon[ x ][ y ] + 1;
                q.push( make_pair( x + dx[ i ], y + dy[ i ] ) );
            }
    }
}

int main() {

    freopen( "barbar.in", "r", stdin );
    freopen( "barbar.out", "w", stdout );

    char s[ DIM ];
    int i, j, l, r, m;

    scanf( "%d %d\n", &N, &M );
    for( i = 1; i <= N; ++i ) {

        gets( s );
        for( j = 0; j < M; ++j )
            switch( s[ j ] ) {

                case '*':
                    harta[ i ][ j ] = -1;
                    break;
                case 'D':
                    harta[ i ][ j ] = -1;
                    dragon[ i ][ j ] = 1;
                    q.push( make_pair( i, j+1 ) );
                    break;
                case 'I':
                    XS = i;
                    YS = j+1;
                    break;
                case 'O':
                    XD = i;
                    YD = j+1;
                    break;
            }
    }

    for( i = 0; i < N+1; ++i )
        dragon[ i ][ 0 ] = dragon[ i ][ M+1 ] = INF;
    for( j = 0; j < M+1; ++j )
        dragon[ 0 ][ j ] = dragon[ N+1 ][ j ] = INF;
    bf_dragon();

//    for( int i = 1; i <= N; ++i ) {
//
//        for( int j = 1; j <= M; ++j )
//            printf( "%d ", dragon[ i ][ j ] );
//        printf( "\n" );
//    }

    l = 1;
    r = max( N, M );
    while( l <= r ) {

        m = (l+r) / 2;
        if( check( m ) ) {

            XXX = m-1;
            r = m-1;
        }
        else
            l = m+1;
    }

    if( XXX )
        printf( "%d", XXX );
    else
        printf( "-1" );

    return 0;
}