Pagini recente » Istoria paginii runda/ceau_oni2017_3 | Cod sursa (job #265788) | Cod sursa (job #2587925) | Cod sursa (job #2304495) | Cod sursa (job #2444519)
#include <fstream>
#include <queue>
#define INF 1012036
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
int n, m, dp[1006][1006][2], dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1}, x, y, xx, yy;
char matrix[1006][1006];
queue <pair <int, int> > coada;
void Read()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
cin >> matrix[i][j];
dp[i][j][0] = INF;
dp[i][j][1] = -INF;
if (matrix[i][j] == 'D')
{
dp[i][j][0] = 0;
coada.push({i, j});
}
if (matrix[i][j] == 'I')
{
x = i;
y = j;
}
if (matrix[i][j] == 'O')
{
xx = i;
yy = j;
}
}
}
}
bool Valid(int i, int j)
{
return i >= 1 && i <= n && j >= 1 && j <= m && matrix[i][j] != '*';
}
bool bfs(int mid)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
dp[i][j][1] = INF;
}
}
if (dp[x][y][0] < mid) return false;
dp[x][y][1] = 0;
coada.push({x, y});
while (!coada.empty())
{
int i = coada.front().first;
int j = coada.front().second;
coada.pop();
for (int k = 0; k < 4; ++k)
{
int ii = i + dx[k];
int jj = j + dy[k];
if (Valid(ii, jj) && dp[ii][jj][1] == INF && dp[ii][jj][0] >= mid)
{
dp[ii][jj][1] = 1 + dp[i][j][1];
coada.push({ii, jj});
}
}
}
if (dp[xx][yy][1] == INF) return false;
return true;
}
void Solve()
{
while (!coada.empty())
{
int i = coada.front().first;
int j = coada.front().second;
coada.pop();
for (int k = 0; k < 4; ++k)
{
int ii = i + dx[k];
int jj = j + dy[k];
if (Valid(ii, jj) && dp[ii][jj][0] > dp[i][j][0] + 1)
{
dp[ii][jj][0] = 1 + dp[i][j][0];
coada.push({ii, jj});
}
}
}
/*
dp[x][y][1] = dp[x][y][0];
coada.push({x, y});
while (!coada.empty())
{
int i = coada.front().first;
int j = coada.front().second;
coada.pop();
for (int k = 0; k < 4; ++k)
{
int ii = i + dx[k];
int jj = j + dy[k];
if (Valid(ii, jj) && dp[ii][jj][1] < min(dp[i][j][1], dp[ii][jj][0]))
{
dp[ii][jj][1] = min(dp[i][j][1], dp[ii][jj][0]);
coada.push({ii, jj});
}
}
}
*/
int st = 1, dr = n * m, sol = -1;
while (st <= dr)
{
int mid = (st + dr) / 2;
if (bfs(mid))
{
sol = mid;
st = mid + 1;
}
else
{
dr = mid - 1;
}
}
cout << sol;
}
int main()
{
Read();
Solve();
return 0;
}