Pagini recente » Cod sursa (job #788326) | Cod sursa (job #1963990) | Cod sursa (job #2209013) | Cod sursa (job #576470) | Cod sursa (job #866937)
Cod sursa(job #866937)
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define pp pair<int,int>
#define mp make_pair
#define ox first
#define oy second
using namespace std;
#define Nmax 1024
const int dl[]={ -1, 0, 1, 0};
const int dc[]={ 0, 1, 0, -1};
int mat[Nmax][Nmax];
bool viz[Nmax][Nmax];
char s[Nmax];
queue <pp> Q;
queue <pp> coada;
int R, C;
int xP, yP;
int xO, yO;
bool verif = false, solutie = false;
int minim;
void citire(){
freopen("barbar.in", "rt", stdin);
scanf("%d %d", &R, &C);
for(int i = 1; i <= R; ++i){
scanf("%s", s);
for(int j = 0; j < C; ++j){
if(s[j] == '*')
mat[i][j+1] = -1;
if(s[j] == 'I')
xP = i, yP = j+1;
if(s[j] == 'O')
xO = i, yO = j+1;
if(s[j] == 'D')
mat[i][j+1] = 0,
Q.push(mp(i,j+1)),
coada.push(mp(i,j+1));
}
}
}
void bordare(){
for(int i = 0; i <= C+1; i++)
mat[0][i] = mat[R+1][i] = -1;
for(int i = 0; i <= R+1; i++)
mat[i][0] = mat[i][C+1] = -1;
}
void lee(){
pp current, vecin;
while(!Q.empty()){
current = Q.front();
Q.pop();
for(int k = 0; k < 4; k++){
vecin.ox = current.ox + dl[k];
vecin.oy = current.oy + dc[k];
if(mat[vecin.ox][vecin.oy] == 0)
mat[vecin.ox][vecin.oy] = mat[current.ox][current.oy] + 1,
Q.push(vecin);
}
}
}
void reinit(){
while(!coada.empty()){
mat[coada.front().ox][coada.front().oy] = 0;
coada.pop();
}
}
void drum(int dist){
pp current, vecin;
while(!Q.empty()){
current = Q.front();
viz[current.ox][current.oy] = true;
Q.pop();
if( current.ox == xO && current.oy == yO ){
solutie = true;
verif = true;
while(!Q.empty())
Q.pop();
}
for(int k = 0; k < 4; k++){
vecin.ox = current.ox + dl[k];
vecin.oy = current.oy + dc[k];
if(mat[vecin.ox][vecin.oy] >= dist && !viz[vecin.ox][vecin.oy])
Q.push(vecin),
viz[vecin.ox][vecin.oy] = true;
}
}
}
void cautare_binara(){
int stanga = -1;
int dreapta = Nmax + Nmax;
int dist;
while ( dreapta - stanga > 1){
dist = (dreapta + stanga) / 2;
verif = false;
memset(viz, false, sizeof(viz));
Q.push(mp(xP, yP));
drum(dist);
if(verif)
stanga = dist;
else
dreapta = dist;
}
minim = min(stanga, mat[xP][yP]);
if(!solutie)
minim = -1;
}
void afis(){
freopen("barbar.out", "w", stdout);
printf("%d\n", minim);
}
int main(){
citire();
bordare();
lee();
reinit();
cautare_binara();
afis();
return 0;
}