Pagini recente » Cod sursa (job #2031184) | Cod sursa (job #775765) | Cod sursa (job #1604572) | Cod sursa (job #2575684) | Cod sursa (job #893360)
Cod sursa(job #893360)
#include <cstdio>
const int MAX_SIZE(1002);
const int WAY(4);
const int X [ ] = {-1,0,1,0};
const int Y [ ] = {0,1,0,-1};
int n, m, best;
int dp [MAX_SIZE] [MAX_SIZE];
bool mark [MAX_SIZE] [MAX_SIZE];
struct coord
{
int i;
int j;
} queue [MAX_SIZE * MAX_SIZE], *pop(queue), *push(queue), start, end;
inline int min (int a, int b)
{
return a < b ? a : b;
}
inline void read (void)
{
std::freopen("barbar.in","r",stdin);
std::scanf("%d %d\n",&n,&m);
int i, j;
char s [MAX_SIZE];
for (i = 1 ; i <= n ; ++i)
{
std::scanf("%s\n",s + 1);
for (j = 1 ; j <= m ; ++j)
if (s[j] == '.')
continue;
else if (s[j] == '*')
dp[i][j] = -1;
else if (s[j] == 'D')
{
dp[i][j] = -1;
push->i = i;
push->j = j;
++push;
}
else if (s[j] == 'I')
{
start.i = i;
start.j = j;
}
else
{
end.i = i;
end.j = j;
}
}
std::fclose(stdin);
}
inline void print (void)
{
std::freopen("barbar.out","w",stdout);
std::printf("%d\n",best ? best : -1);
std::fclose(stdout);
}
inline void isolate (void)
{
int i, a(n + 1), b(m + 1);
for (i = 0 ; i <= a ; ++i)
dp[0][i] = dp[a][i] = -1;
for (i = 0 ; i <= b ; ++i)
dp[i][0] = dp[i][b] = -1;
}
inline void dynamic (void)
{
int i, j, x, y, k;
while (pop < push)
{
i = pop->i;
j = pop->j;
for (k = 0 ; k < WAY ; ++k)
{
x = i + X[k];
y = j + Y[k];
if (!dp[x][y])
{
if (dp[i][j] == -1)
dp[x][y] = 1;
else
dp[x][y] = dp[i][j] + 1;
push->i = x;
push->j = y;
++push;
}
}
++pop;
}
}
inline bool check (int distance)
{
pop = queue;
push = queue + 1;
queue->i = start.i;
queue->j = start.j;
mark[start.i][start.j] = true;
int i, j, x, y, k;
bool found(false);
while (pop < push)
{
i = pop->i;
j = pop->j;
for (k = 0 ; k < WAY ; ++k)
{
x = i + X[k];
y = j + Y[k];
if (x == end.i && y == end.j)
{
found = true;
goto Skip;
}
if (!mark[x][y] && dp[x][y] >= distance)
{
mark[x][y] = true;
push->i = x;
push->j = y;
++push;
}
}
++pop;
}
Skip :
for (register struct coord *iterator(queue) ; iterator < push ; ++iterator)
mark[iterator->i][iterator->j] = false;
return found;
}
inline void search (void)
{
int left(1), right(min(dp[start.i][start.j],dp[end.i][end.j])), middle((left + right) >> 1);
while (left <= right)
{
if (check(middle))
{
best = middle;
left = middle + 1;
}
else
right = middle - 1;
middle = (left + right) >> 1;
}
}
int main (void)
{
read();
isolate();
dynamic();
search();
print();
return 0;
}