Pagini recente » Cod sursa (job #2255696) | Cod sursa (job #1166051) | Cod sursa (job #1548183) | Cod sursa (job #2951225) | Cod sursa (job #2869036)
#include <fstream>
#include <bitset>
#include <queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
const int NMAX = 1e3 + 5;
const int dl[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
queue <pair <int, int>> q;
int dmin_dragon[NMAX][NMAX], n, m;
pair <int, int> start, leave;
void read(){
cin >> n >> m;
char ch;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> ch;
if(ch == 'D'){
q.push({i, j});
dmin_dragon[i][j] = 1;
}
else if(ch == '*')
dmin_dragon[i][j] = -1;
else if(ch == 'I')
start = {i, j};
else if(ch == 'O')
leave = {i, j};
}
}
}
bool inside(int x, int y){
return(x < n && x >= 0 && y < m && y >= 0);
}
void dragon(){
while(!q.empty()){
int f1 = q.front().first;
int f2 = q.front().second;
for(int k = 0; k < 4; k++){
int iv = f1 + dl[k];
int jv = f2 + dc[k];
if(inside(iv, jv) && dmin_dragon[iv][jv] != -1 && (!dmin_dragon[iv][jv] || dmin_dragon[iv][jv] > dmin_dragon[f1][f2] + 1)){
dmin_dragon[iv][jv] = dmin_dragon[f1][f2] + 1;
q.push({iv, jv});
}
}
q.pop();
}
}
bool valid(int dist){
bitset <NMAX> seen[NMAX];
seen[start.first][start.second] = 1;
q.push(start);
if(dmin[start.first][start.second] < dist)
return 0;
while(!q.empty()){
int f1 = q.front().first;
int f2 = q.front().second;
for(int k = 0; k < 4; k++){
int iv = f1 + dl[k];
int jv = f2 + dc[k];
if(inside(iv, jv) && dmin_dragon[iv][jv] != 1 && dmin_dragon[iv][jv] != -1 && !seen[iv][jv] && dmin_dragon[iv][jv] >= dist){
// dmin_dragon[iv][jv] = distanta minima la care se afla un dragon fata de celula (iv, jv)
// daca un dragon se afla mai departe decat distanta pe care am presupus o ca fiind MINIMA, atunci nu ma afecteaza
seen[iv][jv] = 1;
q.push({iv, jv});
}
}
q.pop();
}
return seen[leave.first][leave.second];
}
int bin_search(){
int st = 0, dr = 2e9;
int ans = 0, mid = 0;
while(st <= dr){
// presupun ca mid este distanta cea mai mica la care un dragon se afla pe parcursul unui traseu
mid = ((st + dr) >> 1);
if(valid(mid)){
ans = mid;
st = mid + 1;
}else dr = mid - 1;
}
return --ans;
}
int main(){
read();
dragon();
cout << bin_search();
return 0;
}