Cod sursa(job #482304)

Utilizator SpiderManSimoiu Robert SpiderMan Data 3 septembrie 2010 00:01:14
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
# include <vector>
# include <queue>
using namespace std ;

# define pb push_back
# define mp make_pair
# define ii first
# define jj second

typedef pair < int, int > PR ;
const char FIN[] = "barbar.in" ,
           FOU[] = "barbar.out" ;
const int dx[] = { -1 , 0 , 1 ,  0 } ,
          dy[] = {  0 , 1 , 0 , -1 } ;

PR fir, sec ;
vector < PR > dr ;
short T[1001][1001], TA[1001][1001] ;
int N, M ;
char ch ;

void do_lee ( void ) {
    queue < PR > Q ;

    for ( size_t i = 0, j = dr.size () ; i < j; ++i ) {
	    Q.push ( dr[i] ) ;
	}

    while ( ! Q.empty () ) {
	    PR rec = Q.front () ;
	    Q.pop () ;

	    for ( int k = 0; k < 4; ++k ) {
	        PR act = rec ;
	        act.ii += dx[k], act.jj += dy[k] ;

	        if ( act.ii > 0 && act.ii <= N && act.jj > 0 && act.jj <= M ) {
	            if ( T [ act.ii ][ act.jj ] == 0 ) {
	                T [ act.ii ][ act.jj ] = T [ rec.ii ][ rec.jj ] + 1 ;
	                Q.push ( act ) ;
	            }
	        }
	    }
	}
}

bool check ( int val ) {
    queue < PR > Q ;

	for ( int i = 1; i <= N; ++i ) {
        for ( int j = 1; j <= M; ++j ) {
            TA[i][j] = T[i][j] ;
        }
	}

	if ( TA [ fir.ii ][ fir.jj ] <= val ) {
	    return 0 ;
	}

	TA [ fir.ii ][ fir.jj ] = -1 ;

	Q.push ( fir ) ;

	while ( ! Q.empty () ) {
	    PR rec = Q.front () ;
	    Q.pop () ;

	    for ( int k = 0; k < 4; ++k ) {
	        PR act = rec ;
	        act.ii += dx[k], act.jj += dy[k] ;

	        if ( act.ii > 0 && act.ii <= N && act.jj > 0 && act.jj <= M ) {
	            if ( TA [ act.ii ][ act.jj ] == 0 || TA [ act.ii ][ act.jj ] > val ) {
	                TA [ act.ii ][ act.jj ] = 1 ;
	                Q.push ( act ) ;

	                if ( act == sec ) {
	                    return 1 ;
	                }
	            }
	        }
	    }
	}

	return 0 ;
}

int main ( void ) {
	freopen ( FIN, "r", stdin ) ;

    scanf ( "%d %d\n", &N, &M ) ;

    for ( int i = 1; i <= N; ++i ) {
        for ( int j = 1; j <= M; ++j ) {
            scanf ( " %c", &ch ) ;
            if ( ch == 'D' ) {
                dr.pb ( mp ( i, j ) ) , T[i][j] = 1 ;
            } else if ( ch == '*' ) {
                T[i][j] = 1 ;
            } else if ( ch == 'I' ) {
                fir = mp ( i, j ) ;
            } else if ( ch == 'O' ) {
                sec = mp ( i, j ) ;
            }
        }
    }

    do_lee () ;

	int aux = max ( N, M ), step, i ;
	for ( step = 1; step << 1 <= aux; step <<= 1 ) ;
	for ( i = 0; step; step >>= 1 ) {
		if ( i + step <= aux && check ( i + step ) ) {
			i += step ;
		}
	}

	fprintf ( fopen ( FOU, "w" ) , "%d" , i ? i : -1 ) ;

	return 0 ;
}