Pagini recente » Cod sursa (job #2648179) | Cod sursa (job #2852572) | Cod sursa (job #1621517) | Cod sursa (job #1328015) | Cod sursa (job #1615164)
#include <fstream>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
class Coord {
public:
int x, y;
inline bool operator == (Coord other) {
return x == other.x and y == other.y;
}
};
queue <Coord> q;
Coord paft, drag[1000005], ext;
int n, m, cost[1005][1005], drag_nr = 1, min_cost = INF;
int dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
bool used[1005][1005];
void bord_matrix() {
for(int i = 0; i <= n + 1; ++i) {
cost[i][0] = -1;
cost[i][m + 1] = -1;
}
for(int i = 0; i <= m + 1; ++i) {
cost[0][i] = -1;
cost[n + 1][i] = -1;
}
}
void fill_dragon() {
for(int i = 1; i < drag_nr; ++i) {
cost[drag[i].x][drag[i].y] = 1;
used[drag[i].x][drag[i].y] = true;
q.push(drag[i]);
}
while(!q.empty()) {
Coord frn = q.front();
q.pop();
for(int i = 0; i < 4; ++i) {
int new_x = frn.x + dir[i][0];
int new_y = frn.y + dir[i][1];
if(cost[new_x][new_y] == -1 or used[new_x][new_y]) {
continue;
}
used[new_x][new_y] = true;
if(cost[frn.x][frn.y] + 1 < cost[new_x][new_y] or !cost[new_x][new_y]) {
q.push({new_x, new_y});
cost[new_x][new_y] = cost[frn.x][frn.y] + 1;
}
}
}
}
inline bool bfs(int min_cost) {
q.push(paft);
used[paft.x][paft.y] = true;
if(cost[paft.x][paft.y] < min_cost) {
return false;
}
while(!q.empty()) {
Coord frn = q.front();
q.pop();
for(int i = 0; i < 4; ++i) {
Coord nxt;
nxt.x = frn.x + dir[i][0];
nxt.y = frn.y + dir[i][1];
if(used[nxt.x][nxt.y] or cost[nxt.x][nxt.y] == -1) {
continue;
}
used[nxt.x][nxt.y] = true;
if(cost[nxt.x][nxt.y] >= min_cost) {
q.push(nxt);
if(ext == nxt) {
return true;
}
}
}
}
return false;
}
inline void init_q() {
while(!q.empty()) {
q.pop();
}
}
int bin_search(int l, int r) {
int med, ans = -1;
while(l <= r) {
med = (l + r) / 2;
memset(used, 0, sizeof used);
init_q();
if(bfs(med)) {
l = med + 1;
ans = med;
}
else {
r = med - 1;
}
}
return ans;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
char ch;
cin >> ch;
if(ch == 'I') {
paft = {i, j};
}
else if(ch == 'D') {
drag[drag_nr] = {i, j};
++drag_nr;
}
else if(ch == '*') {
cost[i][j] = -1;
}
else if(ch == 'O') {
ext = {i, j};
}
}
}
bord_matrix();
fill_dragon();
int ans = bin_search(0, n + m + 1);
if(ans != -1) {
--ans;
}
cout << ans << '\n';
return 0;
}