Pagini recente » Cod sursa (job #194918) | Cod sursa (job #3246798) | Cod sursa (job #111385) | Cod sursa (job #2067565) | Cod sursa (job #3316480)
#include <bits/stdc++.h>
#include <fstream>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
const int di[] = {0,0,-1,1}, dj[] = {-1,1,0,0};
const int MAXN = 1005;
const int INF = 1e9;
int n, m;
int a[MAXN][MAXN]; // dragon reach time (0..), wall = -1, unreachable = INF
int h[MAXN][MAXN]; // visited timestamp for barbarian BFS
int si, sj, fi, fj;
bool ok(int i,int j){
return i>=1 && j>=1 && i<=n && j<=m;
}
// check if barbarian, starting after 'wait' minutes (mij), can reach O
bool can_escape(int att, int wait){
// clear the queue used by the barbarian BFS
static queue<pair<short,short>> q;
while(!q.empty()) q.pop();
// if start cell is already reached by dragon before or at 'wait', cannot start
if(a[si][sj] != -1 && a[si][sj] < wait) return false;
if(a[si][sj] == -1) {
// If si,sj is wall (shouldn't be normally), cannot start.
return false;
}
// push start and mark visited with current timestamp
q.push({(short)si,(short)sj});
h[si][sj] = att;
while(!q.empty()){
auto p = q.front(); q.pop();
int i = p.first, j = p.second;
if(i==fi && j==fj) return true; // reached exit
for(int k=0;k<4;k++){
int ni = i + di[k], nj = j + dj[k];
if(!ok(ni,nj)) continue;
if(h[ni][nj] == att) continue; // already visited this run
if(a[ni][nj] == -1) continue; // wall
if(a[ni][nj] < wait) continue; // dragon arrives before/at 'wait' -> unsafe
// safe to push
h[ni][nj] = att;
q.push({(short)ni,(short)nj});
}
}
return false;
}
int main(){
fin >> n >> m;
char c;
// initialize
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j] = INF;
h[i][j] = 0;
}
}
// Read grid and collect dragon sources
queue<pair<int,int>> dq; // dragon BFS queue (separate)
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
fin >> c;
if(c == '*'){
a[i][j] = -1; // wall
} else if(c == 'I'){
si = i; sj = j;
} else if(c == 'O'){
fi = i; fj = j;
} else if(c == 'D'){
a[i][j] = 0; // dragon source reaches here at time 0
dq.push({i,j});
} // empty cells remain INF
}
}
// Dragon BFS: compute earliest time dragon reaches each cell
int maxTime = 0;
while(!dq.empty()){
auto p = dq.front(); dq.pop();
int i = p.first, j = p.second;
int curT = a[i][j]; // non-negative (0..)
for(int k=0;k<4;k++){
int ni = i + di[k], nj = j + dj[k];
if(!ok(ni,nj)) continue;
if(a[ni][nj] != INF) continue; // wall (-1) or already assigned a time
a[ni][nj] = curT + 1;
maxTime = max(maxTime, a[ni][nj]);
dq.push({ni,nj});
}
}
// Binary search over wait time
int st = 0, dr = maxTime; // 0..maxTime inclusive
int rez = -1;
int att = 1; // timestamp marker for h
while(st <= dr){
int mid = (st + dr) / 2;
bool okEscape = can_escape(att, mid);
att++;
if(okEscape){
rez = max(rez, mid);
st = mid + 1;
} else {
dr = mid - 1;
}
}
fout << rez << "\n";
return 0;
}