Pagini recente » Cod sursa (job #1540706) | Cod sursa (job #2698726) | Cod sursa (job #2100624) | Cod sursa (job #1240019) | Cod sursa (job #2707094)
#include <bits/stdc++.h>
//#pragma GCC optimize("O3")
#define test " test "
#define ll long long
#define pii pair<int, int>
#define FASTIO \
cin.tie(0); \
cout.tie(0); \
ios_base::sync_with_stdio(0);
#define FILES \
freopen("barbar.in", "r", stdin); \
freopen("barbar.out", "w", stdout);
#define testcase \
int T; \
cin >> T; \
while (T--)
#define vec vector<int>
using namespace std;
char c[1001][1001];
vector<pii> D;
pii start, finish;
int n, m, dx[] = {0, -1, 0, 1}, dy[] = {-1, 0, 1, 0};
vector<vector<int>> alt;
bool ans[2001];
void drag()
{
queue <pii> q;
for(auto i : D)
q.push(i), alt[i.first][i.second] = 1;
while(!q.empty())
{
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++)
if(x + dx[i] > 0 && x + dx[i] <= n && y + dy[i] > 0 && y + dy[i] <= m)
if(!alt[x + dx[i]][y + dy[i]])
{
alt[x + dx[i]][y + dy[i]] = alt[x][y] + 1;
q.push({x + dx[i], y + dy[i]});
}
}
}
bool lee(int mid)
{
if(ans[mid])
return 1;
vector<vector<bool>> idk;
idk.resize(n + 1, vector<bool>(m + 1));
queue <pii> q;
q.push(start);
idk[start.first][start.second] = 1;
while(!q.empty())
{
int x = q.front().first, y = q.front().second;
q.pop();
for(int i = 0; i < 4; i++)
if(x + dx[i] > 0 && x + dx[i] <= n && y + dy[i] > 0 && y + dy[i] <= m)
{
if(!idk[x + dx[i]][y + dy[i]] && alt[x + dx[i]][y + dy[i]] > mid && c[x + dx[i]][y + dy[i]] != '*')
{
idk[x + dx[i]][y + dy[i]] = 1;
if(make_pair(x + dx[i], y + dy[i]) == finish)
return 1;
else
q.push({x + dx[i], y + dy[i]});
}
}
}
return 0;
}
signed main()
{
FASTIO FILES
cin >> n >> m;
alt.resize(n + 1, vector<int>(m + 1));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
cin >> c[i][j];
if(c[i][j] == 'D')
D.push_back({i, j});
else if(c[i][j] == 'I')
start = {i, j};
else if(c[i][j] == 'O')
finish = {i, j};
}
int mn = INT_MAX;
for(auto i : D)
mn = min(mn, min(abs(i.first - start.first) + abs(i.second - start.second), abs(i.first - finish.first) + abs(i.second - finish.second)));
drag();
int l = 0, r = mn;
while(l < r - 1)
{
int mid = (l + r) / 2;
if(lee(mid))
l = mid, ans[mid] = 1;
else
r = mid;
}
if(lee(l))
cout << l;
else
cout << -1;
return 0;
}