Cod sursa(job #841407)

Utilizator paunmatei7FMI Paun Matei paunmatei7 Data 24 decembrie 2012 09:59:43
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.47 kb
#include<stdio.h>
#include<string.h>
#include<queue>
#define pb push
#define x first
#define y second
using namespace std;
queue < pair < long , long > > v ;
pair < long , long > pozi , pozf , temp , poz ;
long n , m , viz1 [ 1007 ] [ 1007 ] , viz2 [ 1007 ] [ 1007 ] , nr ;
long dx[] = { 0 , 1 , 0 , -1 , 0  } ;
long dy[] = { 0 , 0 , 1 , 0  , -1 } ;
long verif2 ( long i , long j)
{
    if ( viz1 [ i ] [ j ] == -2 && i <= n && j <= m && i >= 1 && j >= 1 ) //daca pot
        return 0 ;
    return 1 ;
}
long verif ( long i , long j , long med )
{
    if ( viz1 [ i ] [ j ] != -1 && viz1 [ i ] [ j ] >= med && viz2 [ i ] [ j ] == 0 && i <= n && j <= m && i >= 1 && j >= 1) //daca pot
        return 0 ;
    return 1 ;
}
bool lee ( long med  , long tip ) // tip daca e 0 e lee din cb altfel e lee din dragoni
{
    if ( tip == 0 )
    {
        if ( viz1 [ pozi . x ] [ pozi . y ] == -2 )
            return 1;
        if ( viz1 [ pozi . x ] [ pozi . y ] < med )
            return 0;
        viz2 [ pozi . x ] [ pozi . y ] = 1 ;
    }
    while ( ! v . empty ( ) )
    {
        temp = v . front ( ) ;
        for ( long k = 1 ; k <= 4 ; ++ k )
        {
            poz . x = temp . x + dx [ k ] ;
            poz . y = temp . y + dy [ k ] ;
            if ( tip == 0 )
            {
                if ( verif ( poz . x , poz . y , med ) == 0 )
                {
                    v . pb ( poz ) ;
                    viz2 [ poz . x ] [ poz . y ] = 1 ; //daca a fost vizitat
                }
            }
            else
            {
                if (verif2 ( poz . x , poz . y ) == 0 )
                {
                    viz1 [ poz . x ][ poz . y ] = viz1 [ temp . x ] [ temp . y ] + 1 ;
                    v . pb ( poz ) ;
                }
            }
        }
        v . pop( ) ;
    }
    return viz2 [ pozf . x ] [ pozf . y ];
}
long cb ( long st , long dr )
{
    long med , last = -1  ;
    while ( st <= dr)
    {
        med = st + ( dr - st ) / 2 ;
        memset ( viz2 , 0 , sizeof ( viz2 ) ) ;
        v . pb ( pozi ) ;
        if ( lee ( med , 0 ) == 0 )
            dr = med - 1 ;
        else
        {
            last = med ;
            st = med + 1 ;
        }
    }
    return last ;
}
int main()
{
    freopen ( "barbar.in" , "r" , stdin ) ;
    freopen ( "barbar.out" , "w" , stdout ) ;
    scanf("%ld %ld\n" , &n , &m ) ;

    for ( long i = 1 ; i <= n ; ++ i )
    {
        for ( long j = 1 ; j <= m ; ++ j )
        {
            char a ;
            scanf("%c" , &a ) ;
            if ( a == 'D' )
            {
                temp . x = temp . y = 0 ;
                temp . x = i ;
                temp . y = j ;
                v . pb ( temp ) ;
                viz1 [ i ] [ j ] = 0 ; //dragoni
            }
            else
            if ( a == '*' )
                viz1 [ i ] [ j ] = -1 ; //obstacol
            else
            if ( a == 'I' )
            {
                viz1 [ i ] [ j ] = -2 ;
                pozi . x = i ;
                pozi . y = j ;
            }
            else
            if ( a == 'O' )
            {
                viz1 [ i ] [ j ] = -2 ;
                pozf . x = i ;
                pozf . y = j ;
            }
            else
                if ( a == '.' )
                viz1 [ i ] [ j ] = -2 ;
        }
        scanf ( "\n" ) ;
    }
    nr = 0 ;
    lee ( 0 , 1  ) ;
    printf("%ld" , cb ( 1 , n * m ) ) ;
    return 0 ;
}