Pagini recente » Cod sursa (job #743168) | Cod sursa (job #1662083) | Cod sursa (job #2699554) | Cod sursa (job #1569266) | Cod sursa (job #1027326)
#include <iostream>
#include <fstream>
#include <queue>
#define MAXSIZE 1001
using namespace std;
class punct {
public:
int x, y;
punct(const int &X = 0, const int &Y = 0): x(X), y(Y) {
}
bool operator ==(const punct &comp) {
return (x == comp.x && y == comp.y);
}
}I, O;
int R, C, dist[MAXSIZE][MAXSIZE];
char mat[MAXSIZE][MAXSIZE];
queue<punct> que;
void input() {
ifstream in("barbar.in");
in >> R >> C;
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
dist[i][j] = 1 << 30;
in >> mat[i][j];
if (mat[i][j] == 'D') {
que.push(punct(j, i));
dist[i][j] = 0;
} else {
if (mat[i][j] == 'I') {
I.x = j;
I.y = i;
} else {
if (mat[i][j] == 'O') {
O.x = j;
O.y = i;
}
}
}
}
}
in.close();
}
bool validPosition(const punct &p) {
return (p.x >= 0 && p.x < C && p.y >= 0 && p.y < R);
}
void generateDist() {
while (!que.empty()) {
punct next = que.front();
que.pop();
punct up(next.x, next.y + 1), right(next.x + 1, next.y), down(next.x, next.y - 1), left(next.x - 1, next.y);
if (validPosition(up) && mat[up.y][up.x] != 'D' && mat[up.y][up.x] != '*' && dist[up.y][up.x] > 1 + dist[next.y][next.x]) {
que.push(up);
dist[up.y][up.x] = 1 + dist[next.y][next.x];
}
if (validPosition(right) && mat[right.y][right.x] != 'D' && mat[right.y][right.x] != '*' && dist[right.y][right.x] > 1 + dist[next.y][next.x]) {
que.push(right);
dist[right.y][right.x] = 1 + dist[next.y][next.x];
}
if (validPosition(down) && mat[down.y][down.x] != 'D' && mat[down.y][down.x] != '*' && dist[down.y][down.x] > 1 + dist[next.y][next.x]) {
que.push(down);
dist[down.y][down.x] = 1 + dist[next.y][next.x];
}
if (validPosition(left) && mat[left.y][left.x] != 'D' && mat[left.y][left.x] != '*' & dist[left.y][left.x] > 1 + dist[next.y][next.x]) {
que.push(left);
dist[left.y][left.x] = 1 + dist[next.y][next.x];
}
}
}
int getMaxDist() {
// intai cautam distanta maxima:
int max_dist = 0;
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
if (max_dist < dist[i][j]) {
max_dist = dist[i][j];
}
}
}
return max_dist;
}
bool seen[MAXSIZE][MAXSIZE];
bool findPath(const int &distanta) {
queue<punct> coada;
coada.push(I);
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
seen[i][j] = 0;
}
}
while (!coada.empty()) {
punct next = coada.front();
seen[next.y][next.x] = 1;
if (next == O) {
return true;
}
coada.pop();
punct up(next.x, next.y + 1), right(next.x + 1, next.y), down(next.x, next.y - 1), left(next.x - 1, next.y);
if (validPosition(up) && !seen[up.y][up.x] && mat[up.y][up.x] != 'D' && mat[up.y][up.x] != '*' && dist[up.y][up.x] >= distanta) {
coada.push(up);
}
if (validPosition(right) && !seen[right.y][right.x] && mat[right.y][right.x] != 'D' && mat[right.y][right.x] != '*' && dist[right.y][right.x] >= distanta) {
coada.push(right);
}
if (validPosition(down) && !seen[down.y][down.x] && mat[down.y][down.x] != 'D' && mat[down.y][down.x] != '*' && dist[down.y][down.x] >= distanta) {
coada.push(down);
}
if (validPosition(left) && !seen[left.y][left.x] && mat[left.y][left.x] != 'D' && mat[left.y][left.x] != '*' && dist[left.y][left.x] >= distanta) {
coada.push(left);
}
}
return false;
}
void binSearch(const int &left, const int &right, int &best) {
if (left > right) {
return;
}
int mid = left + (right - left) / 2;
if (findPath(mid) == true) {
best = mid;
binSearch(mid + 1, right, best);
} else {
binSearch(left, mid - 1, best);
}
}
int solve() {
generateDist();
int max_dist = getMaxDist();
int best = -1;
binSearch(0, max_dist, best);
return best;
}
void output() {
ofstream out("barbar.out");
out << solve();
out.close();
}
int main() {
input();
output();
return 0;
}