Pagini recente » Cod sursa (job #485512) | Cod sursa (job #2130961) | Cod sursa (job #963950) | Cod sursa (job #1176202) | Cod sursa (job #970982)
Cod sursa(job #970982)
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
struct Point {int x, y;};
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int MAX_N = 1005;
const int INF = 1 << 30;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
int N, M;
Point SOURCE, DESTINATION;
int d[MAX_N][MAX_N];
bool visited[MAX_N][MAX_N];
int answer;
void read_input();
void solve();
void print_output();
bool bfs(int min_val = 0);
inline bool is_bounded(int x, int y);
int main() {
read_input();
solve();
print_output();
return 0;
}
void read_input() {
fin >> N >> M;
fin.ignore();
string row;
for (int i = 0; i < N; ++i) {
getline(fin, row);
for (int j = 0; j < M; ++j) {
if (row[j] == 'D') {
d[i + 1][j + 1] = 0;
} else if (row[j] == '*') {
d[i + 1][j + 1] = -1;
} else {
d[i + 1][j + 1] = INF;
if (row[j] == 'I') {
SOURCE = {i + 1, j + 1};
}
if (row[j] == 'O') {
DESTINATION = {i + 1, j + 1};
}
}
}
}
}
void solve() {
queue<Point> q;
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= M; ++j) {
if (d[i][j] == 0) {
q.push({i, j});
}
visited[i][j] = false;
}
}
while (!q.empty()) {
for (int k = 0; k < 4; ++k) {
int x = q.front().x + dx[k];
int y = q.front().y + dy[k];
if (is_bounded(x, y) && d[x][y] == INF) {
d[x][y] = d[q.front().x][q.front().y] + 1;
q.push({x, y});
}
}
q.pop();
}
int lo = 0, hi = N + M;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (bfs(mid)) {
answer = lo;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
if (!bfs(answer)) {
answer = -1;
}
}
void print_output() {
fout << answer;
}
bool bfs(int min_val) {
if (d[SOURCE.x][SOURCE.y] < min_val)
return false;
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= M; ++j) {
visited[i][j] = 0;
}
}
queue<Point> q;
q.push(SOURCE);
while (!q.empty()) {
int x = q.front().x;
int y = q.front().y;
q.pop();
for (int k = 0; k < 4; ++k) {
int xx = x + dx[k];
int yy = y + dy[k];
if (is_bounded(xx, yy)) {
if (d[xx][yy] >= min_val && !visited[xx][yy]) {
if (xx == DESTINATION.x && yy == DESTINATION.y) {
return true;
}
visited[xx][yy] = true;
q.push({xx, yy});
}
}
}
}
return false;
}
inline bool is_bounded(int x, int y) {
if (x < 1 || y < 1) return false;
if (x > N || y > M) return false;
return d[x][y] != -1;
}