Pagini recente » Borderou de evaluare (job #2208889) | Cod sursa (job #1009190) | Cod sursa (job #3260010) | Cod sursa (job #1833027) | Cod sursa (job #1288901)
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int NMAX = 1010, INF = 0x3f3f3f3f;
const int DX[4] = {-1, 0, 0, 1};
const int DY[4] = {0, -1, 1, 0};
int N, M, MinDist[NMAX][NMAX], StartX, StartY, EndX, EndY;
char S[NMAX][NMAX];
bool Can[NMAX][NMAX];
void Process()
{
queue<pair<int, int> > Q;
for(int i = 1; i <= N; ++ i)
for(int j = 1; j <= M; ++ j)
{
MinDist[i][j] = INF;
if(S[i][j] == 'D') Q.push(make_pair(i, j)), MinDist[i][j] = 0;
}
while(!Q.empty())
{
int X = Q.front().first, Y = Q.front().second;
Q.pop();
for(int i = 0; i < 4; ++ i)
{
int NextX = X + DX[i], NextY = Y + DY[i];
if(1 <= NextX && NextX <= N && 1 <= NextY && NextY <= M && MinDist[NextX][NextY] > MinDist[X][Y] + 1 && S[NextX][NextY] != '*')
{
MinDist[NextX][NextY] = MinDist[X][Y] + 1;
Q.push(make_pair(NextX, NextY));
}
}
}
for(int i = 1; i <= N; ++ i)
for(int j = 1; j <= M; ++ j)
if(MinDist[i][j] == INF)
MinDist[i][j] = -1;
}
bool Check(int Min)
{
for(int i = 1; i <= N; ++ i)
for(int j = 1; j <= M; ++ j)
Can[i][j] = 0;
queue<pair<int, int> > Q;
if(MinDist[StartX][StartY] >= Min)
{
Q.push(make_pair(StartX, StartY));
Can[StartX][StartY] = 1;
}
while(!Q.empty())
{
int X = Q.front().first, Y = Q.front().second;
Q.pop();
for(int i = 0; i < 4; ++ i)
{
int NextX = X + DX[i], NextY = Y + DY[i];
if(1 <= NextX && NextX <= N && 1 <= NextY && NextY <= M && !Can[NextX][NextY] && MinDist[NextX][NextY] >= Min && S[NextX][NextY] != '*')
{
Can[NextX][NextY] = 1;
Q.push(make_pair(NextX, NextY));
}
}
}
return Can[EndX][EndY];
}
int main()
{
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
scanf("%i %i\n", &N, &M);
for(int i = 1; i <= N; ++ i)
{
gets(S[i] + 1);
for(int j = 1; j <= M; ++ j)
{
if(S[i][j] == 'I') StartX = i, StartY = j;
if(S[i][j] == 'O') EndX = i, EndY = j;
}
}
Process();
int Left = 0, Right = N * M, Mid, Ans = -1;
while(Left <= Right)
{
Mid = (Left + Right) / 2;
if(Check(Mid)) Ans = Mid, Left = Mid + 1;
else Right = Mid - 1;
}
printf("%i\n", Ans);
}