Pagini recente » Cod sursa (job #2226882) | Cod sursa (job #2154627) | Cod sursa (job #2748210) | Cod sursa (job #762254) | Cod sursa (job #1804881)
#include <fstream>
#include <queue>
using namespace std;
#define INF 1000002
#define NM 1002
ifstream cin("barbar.in");
ofstream cout("barbar.out");
int n, m, x1, y1, x2, y2, d[NM][NM], dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}, dr[NM][NM];
queue<int> q;
bool viz[NM][NM];
char s[NM][NM];
bool coord(int cx, int cy)
{
return (cx > 0 and cx <= n and cy > 0 and cy <= m);
}
void mat(int val)
{
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
viz[i][j] = false;
if(s[i][j] == '.' or s[i][j] == 'I' or s[i][j] == 'O')
{
d[i][j] = val;
}
if(s[i][j] == 'D')
{
d[i][j] = 0;
}
if(s[i][j] == '*')
{
d[i][j] = -1;
}
if(s[i][j] == 'I')
{
x1 = i;
y1 = j;
}
if(s[i][j] == 'O')
{
x2 = i;
y2 = j;
}
}
}
}
void dragon()
{
mat(INF);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
if(s[i][j] == 'D')
{
q.push(i);
q.push(j);
d[i][j] = 0;
}
}
}
while(!q.empty())
{
int x = q.front();
q.pop();
int y = q.front();
q.pop();
for(int i = 0; i < 4; ++i)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(coord(nx, ny))
{
if(d[nx][ny] == INF)
{
d[nx][ny] = d[x][y] + 1;
q.push(nx);
q.push(ny);
}
}
}
}
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
dr[i][j] = d[i][j];
}
}
}
bool exista_drum(int m)
{
mat(-INF);
if(dr[x1][y1] < m)
{
return false;
}
q.push(x1);
q.push(y1);
d[x1][y1] = dr[x1][y1];
viz[x1][y1] = true;
while(!q.empty())
{
int x = q.front();
q.pop();
int y = q.front();
q.pop();
for(int i = 0; i < 4; ++i)
{
int nx = x + dx[i];
int ny = y + dy[i];
if(coord(nx, ny) and s[nx][ny] != '*' and dr[nx][ny] >= m)
{
if(!viz[nx][ny])
{
q.push(nx);
q.push(ny);
viz[nx][ny] = true;
}
}
}
}
return viz[x2][y2];
}
int main()
{
cin >> n >> m;
cin.getline(s[0], 1002);
for(int i = 1; i <= n; ++i)
{
cin.getline(s[i] + 1, m + 2);
}
dragon();
int st = 0, dre = INF, r = -1;
while(st <= dre)
{
int m = (st + dre) / 2;
if(exista_drum(m))
{
r = m;
st = m + 1;
}
else
{
dre = m - 1;
}
}
cout << r << '\n';
return 0;
}