Pagini recente » Cod sursa (job #1651393) | Cod sursa (job #699653) | Cod sursa (job #1368167) | Cod sursa (job #2444230) | Cod sursa (job #44361)
Cod sursa(job #44361)
#include <stdio.h>
#include <memory.h>
#include <string.h>
#define NMAX 1510
typedef struct coada
{
int x, y;
};
char a[NMAX][NMAX];
coada c[250000];
int n, m;
int min[NMAX][NMAX];
int inc, sf = -1;
int inx, iny, outx, outy;
int until[NMAX][NMAX];
void bordare()
{
int i;
for(i = 0; i <= n+1; ++i)
{
a[i][0] = a[i][m+1] = '*';
}
for(i = 0; i <= m+1; ++i)
{
a[0][i] = a[n+1][i] = '*';
}
}
void read()
{
int i, j;
scanf("%d %d\n", &n, &m);
bordare();
for(i = 1; i <= n; ++i)
{
scanf("%s\n", a[i]+1);
for(j = 1; j <= m; ++j)
{
if(a[i][j] == 'D')
{
c[++sf].x = i;
c[sf].y = j;
min[i][j] = 0;
}
else if(a[i][j] == 'I')
{
inx = i;
iny = j;
a[i][j] = '.';
}
else if(a[i][j] == 'O')
{
outx = i;
outy = j;
a[i][j] = '.';
}
}
}
}
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
void lee_dragoni()
{
int x, y;
int i;
int nextx, nexty;
while(inc <= sf)
{
x = c[inc].x;
y = c[inc++].y;
for(i = 0; i < 4; ++i)
{
nextx = x + dx[i];
nexty = y + dy[i];
if((a[nextx][nexty] == '.') && (min[nextx][nexty] > min[x][y] + 1))
{
c[++sf].x = nextx;
c[sf].y = nexty;
min[nextx][nexty] = min[x][y] + 1;
}
}
}
}
void print_min()
{
int i, j;
for(i = 0; i <= n+1; ++i)
{
for(j = 0; j <= m+1; ++j)
{
printf("%d ", min[i][j]);
}
printf("\n");
}
}
void print_a()
{
int i, j;
printf("\n");
for(i = 0; i <= n+1; ++i)
{
for(j = 0; j <= m+2; ++j)
{
printf("%c ", a[i][j]);
}
printf("\n");
}
}
int lee_in_out(int m)
{
int x, y;
coada c[250000];
int inc, sf;
int nextx, nexty;
int j;
//memset(c, 0, sizeof(c));
memset(until, 0, sizeof(until));
c[0].x = inx;
c[0].y = iny;
inc = sf = 0;
while(inc <= sf)
{
x = c[inc].x;
y = c[inc++].y;
for(j = 0; j < 4; ++j)
{
nextx = x + dx[j];
nexty = y + dy[j];
if(a[nextx][nexty] != '*' && min[nextx][nexty] >= m && !until[nextx][nexty])
{
c[++sf].x = nextx;
c[sf].y = nexty;
++until[nextx][nexty];
}
if(nextx == outx && nexty == outy)
{
return 1;
}
}
}
return 0;
}
void binary_search()
{
int st, dr;
int mijloc;
int keep = -1;
st = 1;
dr = (n + m) * 5;
while(st <= dr)
{
m = (st + dr)/2;
if(lee_in_out(m))
{
st = m+1;
keep = m;
}
else
{
dr = m-1;
}
}
printf("%d\n", keep);
}
int main()
{
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
memset(min, 0x3f, sizeof(min));
read();
lee_dragoni();
//print_min();
//print_a();
binary_search();
fclose(stdin);
fclose(stdout);
return 0;
}