Pagini recente » Monitorul de evaluare | Monitorul de evaluare | Profil Saitama | Istoria paginii runda/contest01 | Cod sursa (job #2912077)
#include <fstream>
#include <string>
#include <queue>
#pragma optimize GCC ("Ofast")
#define int long long
using namespace std;
ifstream cin ("barbar.in");
ofstream cout ("barbar.out");
using your_mom = pair <int, int>;
const int N = 1030;
int a[N + 1][N + 1], d[N + 1][N + 1], b[N + 1][N + 1];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
queue <your_mom> q, qd;
string s;
int n, m, ci, cf, li, lf;
bool inside (int x, int y)
{
return (x >= 1 && x <= n && y >= 1 && y <= m);
}
bool oklee (int val)
{
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
a[i][j] = b[i][j];
if (d[li][ci] <= val)
return 0;
q.push({li, ci});
a[li][ci] = 1;
while (!q.empty())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (inside (xx, yy) && !a[xx][yy] && d[xx][yy] > val)
a[xx][yy] = a[x][y] + 1, q.push({xx, yy});
}
}
if (a[lf][cf])
return 1;
return 0;
}
int cb (int st, int dr)
{
int med, last = -1;
while (st <= dr)
{
int med = (st + dr) >> 1;
if (oklee (med))
{
st = med + 1;
last = med;
}
else
dr = med - 1;
}
return last;
}
void precalc ()
{
while (!qd.empty())
{
int x = qd.front().first;
int y = qd.front().second;
qd.pop();
for (int i = 0; i < 4; ++i)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (inside (xx, yy) && !d[xx][yy])
d[xx][yy] = d[x][y] + 1, qd.push({xx, yy});
}
}
}
signed main()
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
cin >> s;
for (int j = 0; j < s.size(); ++j)
{
if (s[j] == 'I')
ci = j + 1, li = i;
if (s[j] == 'O')
cf = j + 1, lf = i;
if (s[j] == 'D')
qd.push({i, j + 1}), d[i][j + 1] = 1, a[i][j + 1] = b[i][j + 1] = -1;
if (s[j] == '*')
a[i][j + 1] = b[i][j + 1] = -1;
}
}
precalc();
int valcb = cb (1, N * N);
cout << valcb << '\n';
return 0;
}