Cod sursa(job #830925)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 7 decembrie 2012 21:07:37
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;
const char iname[] = "barbar.in";
const char oname[] = "barbar.out";
ifstream fin(iname);
ofstream fout(oname);
int a[ 1005 ][ 1005 ], d[ 1005 ][ 1005 ], viz[ 1005 ][ 1005 ];
int dl[]={0,1,0,-1};
int dc[]={-1,0,1,0};
struct nod{
	int x,y;
} start, stop, temp, nou;
queue <nod> q;
// verific , daca ,, p '' reprezinta o distanta valida
// daca traseul este posibil , astfel incat la fiecare pas , Paftenie este la o distanta
// >= cu p 
bool traseu( int p )
{
	if ( d[ start.x ][ start.y ] < p ) return 0;
    q.push( start );
    memset( viz , 0 , sizeof( viz ) );
    viz[ start.x ][ start.y ] = 1;
    while ( !q.empty() )
    {   
		temp = q.front(); 
		q.pop();
        for( int lin , col , k=0; k < 4; ++k )
        {   
			lin = temp.x + dl[ k ]; 
			col = temp.y + dc[ k ];
            if ( d[ lin ][ col ] >= p && !viz[ lin ][ col ] )
            {   
				viz[ lin ][ col ] = 1;
                nou.x = lin; 
				nou.y = col; 
				q.push(nou);
            }
        }
    }
    return viz[ stop.x ][ stop.y ];
}
int main()
{
	int n, m;    
	char ch;
    fin >> n >> m;
    for(int i = 1; i <= n; ++i )
        for(int j = 1; j <= m; ++j )
            d[ i ][ j ] = -2;
    for(int i=0; i<=n+1; ++i) d[i][0]=d[i][m+1]=-1;
    for(int i=0; i<=m+1; ++i) d[0][i]=d[n+1][i]=-1;
    for( int i = 1; i <= n; ++i )
        for( int j = 1; j <= m; ++j )
        {   
			fin >> ch;
            switch( ch )
            {   case '*' : d[ i ][ j ] = -1; break;
                case 'O' : stop.x = i; stop.y = j; break;
                case 'I' : start.x = i; start.y = j; break;
                case 'D' : d[ i ][ j ] = 0; nou.x = i; nou.y = j; q.push( nou ); break;
            }
        }
	// vom precalcula matricea D , astfel incat ea va contine distantele minime
	// pornind de la fiecare dragon in parte
	// ne folosim de algoritmul lui Lee 
	while( !q.empty() )
    {   
		temp = q.front(); 
		q.pop();
        for ( int lin , col , k=0; k < 4; ++k )
		{
			lin = temp.x + dl[ k ]; 
			col = temp.y + dc[ k ];
			if ( d[ lin ][ col ]== -2 )
			{
				d[ lin ][ col ] = d[ temp.x ][ temp.y ] + 1; 
				nou.x = lin; 
				nou.y = col; 
				q.push(nou);
			}
		}
	}
    int dist = -1;
	// distanta , se afla optim folosind cautarea binara
	// daca avem un traseu posibil cu conditia curenta ,, p '' , atunci 
	// retinem distanta , valoare curenta din cautare , pana cand st > dr 
	// in final , in dist , vom avea valoarea maxima , la care Paftenie se poate afla
	// fata de orice Dragon din temnita
	if ( d[ start.x ][ start.y ] != -2 )
    {   
		int st = 0, dr = n * m , mij;
        while ( st <= dr )
        {   
			mij = ( st + dr ) >> 1;
            if( traseu( mij ) )
			{ 
				dist = mij; 
				st = mij + 1;
			} 
			else dr = mij - 1;
        }
    }
    fout << dist << '\n'; 
	return 0;
}