Pagini recente » Cod sursa (job #166231) | Cod sursa (job #606718) | Cod sursa (job #1474312) | Cod sursa (job #1599893) | Cod sursa (job #27824)
Cod sursa(job #27824)
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define FIN "barbar.in"
#define FOUT "barbar.out"
#define MAX 1001
#define BIG_ONE 10000002
struct point
{
long x, y, v;
};
long R, C;
char A[MAX][MAX];
long V[MAX][MAX];
long B[MAX][MAX];
point mv[4] = {{-1,0},{1,0},{0,1},{0,-1}}; // vector of moves
queue <point> D;
point I, O;
long answer=0;
void read_data()
{
long i, j;
freopen(FIN, "r", stdin);
scanf("%ld %ld", &R, &C);
for (i=0; i<R; ++i)
for (j=0; j<C; ++j)
{
scanf("%c", A[i]+j);
while ( A[i][j]=='\n' && !feof(stdin) ) scanf("%c", A[i]+j);
if ( A[i][j]=='D' ) // dragon - queue
{
point tmp;
tmp.x = i; tmp.y = j; tmp.v = 0;
D.push(tmp);
}
if ( A[i][j]=='I' ) // initial point
{
I.x = i;
I.y = j;
}
if ( A[i][j]=='O' )
{
O.x = i;
O.y = j;
}
}
fclose(stdin);
}
void debug();
void solve()
{
long i, j, mx=0;
for (i=0; i<R; ++i)
for (j=0; j<C; ++j)
V[i][j]= BIG_ONE ;
// expand all the dragons with a fill-based procedure, optimized with a queue (D)
while ( !D.empty() )
{
point tmp = D.front();
// printf("%ld %ld\n", tmp.x, tmp.y);
V[ tmp.x ][ tmp.y ] = tmp.v;
for (i=0; i<4; ++i)
{
point next;
next.x = tmp.x + mv[i].x; next.y = tmp.y + mv[i].y;
if ( next.x>=0 && next.x<R && next.y>=0 && next.y<C )
if ( V[ next.x ][ next.y ] > tmp.v + 1 && A[ next.x ][ next.y ]!='*')
{
V[ next.x ][ next.y ] = next.v = tmp.v + 1;
if ( tmp.v+1>mx ) mx = tmp.v+1;
D.push(next);
}
}
D.pop();
}
// binary search of x -> minimum, where x is the smallest value on the path
long l=0, r=mx;
while ( l<=r )
{
long m = (l+r)/2;
long ok=1;
memset(B, 0, sizeof(B));
while ( !D.empty() ) D.pop();
// same fill procedure;
D.push(I);
while ( !D.empty() && ok )
{
point tmp = D.front();
// printf("%ld %ld\n", tmp.x, tmp.y);
B[tmp.x][tmp.y]=1;
for (i=0; i<4; ++i)
{
point next;
next.x = tmp.x + mv[i].x; next.y = tmp.y + mv[i].y;
if ( next.x>=0 && next.x<R && next.y>=0 && next.y<C )
if ( V[next.x][next.y]>=m && !B[next.x][next.y] && A[next.x][next.y]!='*' )
{
if ( next.x==O.x && next.y==O.y )
ok=0;
D.push(next);
}
}
D.pop();
}
// modify the right and left limits of the bsearch
if ( !ok ) // found path
{
if ( answer<m )
{
answer=m;
// debug();
}
l = m+1;
}
else
{
r = m-1;
}
}
}
void debug()
{
long i,j;
for (i=0; i<R; ++i)
{
for (j=0; j<C; ++j)
if ( V[i][j]!= BIG_ONE )
printf("%6ld ", B[i][j]);
else
printf(" MARE ");
printf("\n");
}
printf("\n\n");
}
void write_data()
{
freopen(FOUT, "w", stdout);
printf("%ld\n", answer);
fclose(stdout);
}
int main()
{
read_data();
solve();
write_data();
return 0;
}