Pagini recente » Cod sursa (job #3189808) | Cod sursa (job #1558623) | Cod sursa (job #2851086) | Cod sursa (job #2885021) | Cod sursa (job #1615159)
#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;
}
};
class PrioQ {
public:
int cost/*, dist*/;
Coord pos;
};
class cmp {
public:
inline bool operator ()(PrioQ a, PrioQ b) {
return a.cost < b.cost;
}
};
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;
}
}
}
}
void print_used() {
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
cout << used[i][j] << ' ';
}
cout << '\n';
}
cout << '\n';
}
void print_cost() {
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
cout << cost[i][j] << ' ';
}
cout << '\n';
}
cout << '\n';
}
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()) {
/*if(min_cost == 5) {
print_used();
}*/
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(med == 5) {
///debug
int a = 0;
++a;
}*/
if(bfs(med)) {
/*if(med == 5) {
print_used();
}*/
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();
/*for(int i = 1; i <= drag_nr - 1; ++i) {
memset(used, 0, sizeof used);
fill_dragon(drag[i]);
//print_cost();
}*/
fill_dragon();
//print_cost();
int ans = bin_search(0, n + m + 1);
if(ans != -1) {
--ans;
}
cout << ans << '\n';
return 0;
}