Pagini recente » Diferente pentru utilizator/mihaistamatescu intre reviziile 40 si 39 | Cod sursa (job #1720153) | Istoria paginii runda/pregatire_ichb_2017 | Cod sursa (job #23786) | Cod sursa (job #193040)
Cod sursa(job #193040)
#include <cstdio>
#include <cstring>
using namespace std;
#define FIN "barbar.in"
#define FOUT "barbar.out"
#define MOD 200000
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, -1, 0, 1};
#define MAX_N 1005
unsigned char A[MAX_N][MAX_N];
int Mat[MAX_N][MAX_N];
#define MAX_C 200005
typedef struct point { int x, y;};
point C[MAX_C];
int N, M;
int li, lf;
int Dmax, BEST; // solutii
int inx, iny;
int outx, outy;
void readdata ()
{
scanf ("%d %d\n", &N, &M);
int i, j, L;
char S[MAX_N];
for (i = 1; i <= N; ++i)
{
gets (S), L = strlen (S) - 1;
for (j = 0; j <= L; ++j)
A[i][j + 1] = S[j];
}
}
inline int ok (int x, int y)
{
if (!x || !y || (x == N + 1) || (y == M + 1)) return 0;
return 1;
}
void dist ()
{
int i, j;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
{
if (A[i][j] == 'D') C[(++lf) % MOD].x = i, C[lf % MOD].y = j;
if (A[i][j] == 'I') inx = i, iny = j;
if (A[i][j] == 'O') outx = i, outy = j;
}
A[inx][iny] = A[outx][outy] = '.';
while (li < lf)
{
int x, y;
x = C[(++li) % MOD].x, y = C[(li) % MOD].y;
for (i = 0; i < 4; ++i)
if (A[x + dx[i]][y + dy[i]] == '.' && !Mat[x + dx[i]][y + dy[i]])
{
C[(++lf) % MOD].x = x + dx[i], C[lf % MOD].y = y + dy[i];
Mat[x + dx[i]][y + dy[i]] = Mat[x][y] + 1;
if (Mat[x][y] + 1 > Dmax) Dmax = Mat[x][y] + 1;
}
}
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
if (A[i][j] == 'D') Mat[i][j] = 0;
}
int path (int c)
{
int i;
li = lf = 0;
memset (A, 0, sizeof (A));
if (Mat[inx][iny] < c) return 0;
C[++lf].x = inx, C[lf].y = iny;
while (li < lf)
{
int x, y;
x = C[(++li) % MOD].x, y = C[li % MOD].y;
for (i = 0; i < 4; ++i)
if (A[x + dx[i]][y + dy[i]] == 0 && Mat[x + dx[i]][y + dy[i]] >= c && ok(x + dx[i], y + dy[i]))
{
C[(++lf) % MOD].x = x + dx[i], C[lf % MOD].y = y + dy[i];
A[x + dx[i]][y + dy[i]] = 1;
if (x + dx[i] == outx && y + dy[i] == outy)
return 1;
}
}
return 0;
}
int main ()
{
freopen (FIN, "r", stdin);
freopen (FOUT, "w", stdout);
readdata ();
dist ();
/*
int i, j;
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
printf ("%d ", Mat[i][j]);
printf ("\n");
}
*/
int st, dr, m;
st = 1, dr = Dmax;
BEST = -1;
while (st <= dr)
{
m = (st + dr) >> 1;
int p = path (m);
if (p) BEST = m;
if (p) st = m + 1;
else dr = m - 1;
}
printf ("%d\n", (int) BEST);
return 0;
}