Pagini recente » Cod sursa (job #207231) | Cod sursa (job #2904584) | Cod sursa (job #130244) | Cod sursa (job #3253941) | Cod sursa (job #1425766)
#include <stdio.h>
#include <string.h>
#include <vector>
#define NMAX 1001
#define DRAGON 'D'
#define EMPTY '.'
#define START 'I'
#define END 'O'
#define VECINI 4
using namespace std;
int r, c, dist[NMAX][NMAX], dMax = 0, dMin = 1 << 30, coada[2][NMAX * NMAX + NMAX], viz[NMAX][NMAX], startI, startJ, endI, endJ, ans;
int veciniI[] = { -1, 0, 0, 1}, veciniJ[] = { 0, -1, 1, 0};
char matrix[NMAX][NMAX];
vector< pair<int, int> > dragoni;
int validIndexes(int i, int j) {
if(i < 0 || i >= r) return 0;
if(j < 0 || j >= c) return 0;
return 1;
}
void distDragoni() {
int currI, currJ, newI, newJ, first, last;
first = 0;
last = -1;
for(int i = 0; i < dragoni.size(); ++i) {
coada[0][++last] = dragoni[i].first;
coada[1][last] = dragoni[i].second;
dist[dragoni[i].first][dragoni[i].second] = 1;
}
while(first <= last) {
currI = coada[0][first];
currJ = coada[1][first];
for(int i = 0; i < VECINI; ++i) {
newI = currI + veciniI[i];
newJ = currJ + veciniJ[i];
if(validIndexes(newI, newJ) && !dist[newI][newJ] && matrix[newI][newJ] == EMPTY
|| matrix[newI][newJ] == START || matrix[newI][newJ] == END) {
coada[0][++last] = newI;
coada[1][last] = newJ;
dist[newI][newJ] = dist[currI][currJ] + 1;
if(dist[newI][newJ] < dMin) dMin = dist[newI][newJ];
if(dist[newI][newJ] > dMax) dMax = dist[newI][newJ];
}
}
++first;
}
}
int bfs(int limit) {
int currI, currJ, newI, newJ, first, last;
if(dist[startI][startJ] < limit || dist[endI][endJ] < limit) return 0;
for(int i = 0; i < r; ++i)
for(int j = 0; j < c; ++j)
viz[i][j] = 0;
first = last = 0;
coada[0][0] = startI;
coada[1][0] = startJ;
viz[startI][startJ] = 1;
while(first <= last) {
currI = coada[0][first];
currJ = coada[1][first];
for(int i = 0; i < VECINI; ++i) {
newI = currI + veciniI[i];
newJ = currJ + veciniJ[i];
if(validIndexes(newI, newJ) && !viz[newI][newJ] && dist[newI][newJ] >= limit) {
coada[0][++last] = newI;
coada[1][last] = newJ;
viz[newI][newJ] = 1;
if(newI == endI && newJ == endJ) return 1;
}
}
++first;
}
return 0;
}
void solve() {
int m, canBeDone;
ans = -1;
distDragoni();
while(dMin <= dMax) {
m = (dMin + dMax) / 2;
canBeDone = bfs(m);
if(canBeDone && canBeDone > ans) ans = m;
if(canBeDone) {
dMin = m + 1;
}
else {
dMax = m - 1;
}
}
}
int main() {
freopen("barbar.in", "r", stdin);
freopen("barbar.out", "w", stdout);
scanf("%d%d%*c", &r, &c);
for(int i = 0; i < r; ++i) {
scanf("%s", matrix[i]);
int index = 0;
while(matrix[i][index]) {
if(matrix[i][index] == DRAGON)
dragoni.push_back(make_pair(i, index));
if(matrix[i][index] == START) {
startI = i;
startJ = index;
}
if(matrix[i][index] == END) {
endI = i;
endJ = index;
}
++index;
}
}
solve();
printf("%d", ans - 1);
return 0;
}