Pagini recente » Cod sursa (job #3336700) | Cod sursa (job #792734) | Cod sursa (job #1006385) | Cod sursa (job #796431) | Cod sursa (job #3310604)
#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#include <cstring>
#include <fstream>
using namespace std;
using ll = long long;
#define fast_io ios::sync_with_stdio(false); fin.tie(nullptr);
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define vec_read(v, n) \
for (int i = 0; i < (n); i++) { \
fin >> v[i]; \
}
#define vec_print(v, n, sp) \
for (int i = 0; i < (n); i++) { \
fout << v[i] << sp; \
} \
fout << '\n';
#define vec_print_rev(v, n, sp) \
for (int i = (n) - 1; i>= 0; i--) { \
fout << v[i] << sp; \
} \
fout << '\n';
#ifdef LOCAL
#define dbg(x) cerr << #x << " = " << (x) << '\n'
#else
#define dbg(x)
#endif
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e3 + 5;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
pair<int,int> dirs[] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int n, m;
char mat[MAXN][MAXN];
int distances[MAXN][MAXN];
vector<pair<int, int>> dragons;
pair<int, int> start, finish;
bool visited[MAXN][MAXN];
void ReadData() {
fin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
fin >> mat[i][j];
if (mat[i][j] == 'D') {
dragons.push_back({i, j});
} else if (mat[i][j] == 'I') {
start = {i, j};
} else if (mat[i][j] == 'O') {
finish = {i, j};
}
}
}
}
bool InBounds(pair<int, int>& dir) {
return !(dir.first < 0 || dir.second < 0 || dir.first >= n || dir.second >= m);
}
void BuildDistances() {
for (int i = 0; i < n; i++) {
memset(distances[i], INF, sizeof(distances[i]));
}
queue<pair<int,int>> q;
for (auto d : dragons) {
distances[d.first][d.second] = 0;
q.push(d);
}
while (!q.empty()) {
auto d = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
pair<int,int> dir = {d.first + dirs[i].first, d.second + dirs[i].second};
if (!InBounds(dir)) {
continue;
}
if (mat[dir.first][dir.second] == '*' ||
mat[dir.first][dir.second] == 'D') {
continue;
}
if (distances[dir.first][dir.second] != INF) {
continue;
}
distances[dir.first][dir.second] = distances[d.first][d.second] + 1;
q.push(dir);
}
}
}
struct Cell {
pair<int, int> pos;
int val;
bool operator <(const Cell& other) const {
return val < other.val;
}
};
int BuildPath(int dist) {
queue<Cell> q;
q.push({start, distances[start.first][start.second]});
int ans = INF;
for (int i = 0; i < n; i++) {
memset(visited[i], 0, sizeof(visited[i]));
}
visited[start.first][start.second] = 1;
while (!q.empty()) {
auto d = q.front();
q.pop();
ans = min(ans, distances[d.pos.first][d.pos.second]);
if (d.pos == finish) {
return ans;
}
for (int i = 0; i < 4; i++) {
pair<int,int> dir = {d.pos.first + dirs[i].first, d.pos.second + dirs[i].second};
if (!InBounds(dir)) {
continue;
}
if (mat[dir.first][dir.second] == '*' ||
mat[dir.first][dir.second] == 'D') {
continue;
}
if (visited[dir.first][dir.second]) {
continue;
}
if (distances[dir.first][dir.second] < dist) {
continue;
}
q.push({dir, distances[dir.first][dir.second]});
visited[dir.first][dir.second] = true;
}
}
return -1;
}
void Solve() {
BuildDistances();
int lf = 0;
int rg = n + m + 1;
int mid;
int ans = -1;
while (lf <= rg) {
mid = lf + (rg - lf) / 2;
if (BuildPath(mid) != -1) {
lf = mid + 1;
ans = max(ans, mid);
} else {
rg = mid - 1;
}
}
fout << ans << '\n';
}
int main() {
// fast_io;
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int T = 1;
// fin >> T;
while (T--) {
ReadData();
Solve();
}
return 0;
}