Pagini recente » Cod sursa (job #811154) | Cod sursa (job #3332833) | Cod sursa (job #2224504) | Cod sursa (job #2729464) | Cod sursa (job #3306807)
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
int mat[1001][1001];
int way[1001][1001] = {0};
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m;
int x_in, y_in, x_out, y_out;
int max_k = -1;
/*
. = -1
D = 0
* = -2
*/
queue<pair<int, int>> q;
inline bool inside(int i, int j)
{
return i >= 1 && j >= 1 && i <= n && j <= m;
}
void lee()
{
while (!q.empty())
{
int x = q.front().first, y = q.front().second;
q.pop();
for (int k = 0; k < 4; ++k)
{
int nx = x + dx[k], ny = y + dy[k];
if (inside(nx, ny) && mat[nx][ny] == -1)
{
mat[nx][ny] = mat[x][y] + 1;
q.push({nx, ny});
if (mat[nx][ny] > max_k)
max_k = mat[nx][ny];
}
}
}
}
void drum(int distance)
{
q.push({x_in, y_in});
way[x_in][y_in] = 1;
if (mat[x_in][y_in] < distance)
return;
while (!q.empty())
{
int x = q.front().first, y = q.front().second;
q.pop();
for (int k = 0; k < 4; ++k)
{
int nx = x + dx[k], ny = y + dy[k];
if (inside(nx, ny) && mat[nx][ny] >= distance && way[nx][ny] == 0)
{
way[nx][ny] = way[x][y] + 1;
q.push({nx, ny});
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
char c;
cin >> c;
if (c == '.')
mat[i][j] = -1;
if (c == 'D')
{
mat[i][j] = 0;
q.push({i, j});
}
if (c == '*')
mat[i][j] = -2;
if (c == 'I')
{
x_in = i;
y_in = j;
mat[i][j] = -1;
}
if (c == 'O')
{
x_out = i;
y_out = j;
mat[i][j] = -1;
}
}
}
// lee multisource dragoni
lee();
int st = 0, dr = max_k;
int ans = -1;
while (st <= dr)
{
int mj = (st + dr) / 2;
drum(mj);
if (way[x_out][y_out] != 0)
{
st = mj + 1;
ans = mj;
}
else
dr = mj - 1;
memset(way, 0, sizeof(way));
}
cout << ans;
return 0;
}