Pagini recente » Cod sursa (job #339996) | Cod sursa (job #2077486) | Cod sursa (job #1234972) | Cod sursa (job #2376503) | Cod sursa (job #1492445)
#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
#define IN -1
#define OUT -2
#define DRAGON 0
#define FREE -3
#define BLOCKED -4
using namespace std;
typedef struct {
int i, j;
int d;
} TPos;
typedef struct compare {
bool operator () (const TPos a, const TPos b) {
return a.d < b.d;
}
} compare;
int R, C, Ii, Ij, m = 99999999, reached;
int M[1005][1005];
vector <TPos> H;
bool comp (TPos a, TPos b) {
return (a.d < b.d) ? true : false;
}
void read() {
scanf("%d %d\n", &R, &C);
char buffer[1005];
for (int i = 0; i < R; ++i) {
fgets(buffer, 1005, stdin);
for (int j = 0; j < C; ++j) {
switch (buffer[j]) {
case '.': M[i][j] = FREE; break;
case 'D': M[i][j] = DRAGON; break;
case '*': M[i][j] = BLOCKED; break;
case 'O': M[i][j] = OUT; break;
case 'I': {
M[i][j] = IN;
Ii = i; Ij = j;
break;
}
default: break;
}
}
}
}
int findDist (int i, int j) {
int dist[1005][1005] = {{0}};
dist[i][j] = 1;
queue < pair <int, int> > Q;
Q.push(make_pair(i, j));
while (!Q.empty()) {
auto c = Q.front();
if (M[c.first][c.second] == DRAGON) return dist[c.first][c.second]-1;
if (c.first > 0 && !dist[c.first-1][c.second] && M[c.first-1][c.second] > BLOCKED) {
dist[c.first-1][c.second] = dist[c.first][c.second] + 1;
Q.push(make_pair(c.first-1, c.second));
}
if (c.first < R-1 && !dist[c.first+1][c.second] && M[c.first+1][c.second] > BLOCKED) {
dist[c.first+1][c.second] = dist[c.first][c.second] + 1;
Q.push(make_pair(c.first+1, c.second));
}
if (c.second > 0 && !dist[c.first][c.second-1] && M[c.first][c.second-1] > BLOCKED) {
dist[c.first][c.second-1] = dist[c.first][c.second] + 1;
Q.push(make_pair(c.first, c.second - 1));
}
if (c.second < C-1 && !dist[c.first][c.second+1] && M[c.first][c.second+1] > BLOCKED) {
dist[c.first][c.second+1] = dist[c.first][c.second] + 1;
Q.push(make_pair(c.first, c.second + 1));
}
Q.pop();
}
return -999; //shouldn't happen
}
//find path with min dist d if possible
int bf (int d) {
bool visited[1005][1005];
visited[Ii][Ij] = true;
queue < pair <int, int> > Q;
Q.push(make_pair(Ii, Ij));
while (!Q.empty()) {
auto c = Q.front();
Q.pop();
if (M[c.first][c.second] == OUT) return 1;
if (c.first && (M[c.first-1][c.second] >= d || M[c.first-1][c.second] == OUT) && !visited[c.first-1][c.second]) {
Q.push(make_pair(c.first-1, c.second));
visited[c.first-1][c.second] = true;
}
if (c.first < R-1 && (M[c.first+1][c.second] >= d || M[c.first+1][c.second] == OUT) && !visited[c.first+1][c.second]) {
Q.push(make_pair(c.first+1, c.second));
visited[c.first+1][c.second] = true;
}
if (c.second && (M[c.first][c.second-1] >= d || M[c.first][c.second-1] == OUT) && !visited[c.first][c.second-1]) {
Q.push(make_pair(c.first, c.second-1));
visited[c.first][c.second-1] = true;
}
if (c.second < C-1 && (M[c.first][c.second+1] >= d || M[c.first][c.second+1] == OUT) && !visited[c.first][c.second+1]) {
Q.push(make_pair(c.first, c.second+1));
visited[c.first][c.second+1] = true;
}
}
return 0;
}
int maxdist (int max) {
int l = 0, r = max, mid;
while (l < r) {
mid = (l + r) / 2;
if (bf(mid)) {
l = mid;
} else {
r = mid;
}
}
return mid;
}
int fillM () {
int max = 0;
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
if (M[i][j] == FREE) {
M[i][j] = findDist(i, j);
if (M[i][j] > max) max = M[i][j];
}
}
}
return max;
}
int main (void) {
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
read();
int max = fillM();
printf("%d", maxdist(max));
return 0;
}