Pagini recente » Cod sursa (job #774285) | Cod sursa (job #1333949) | Cod sursa (job #2616477) | Cod sursa (job #446821) | Cod sursa (job #2562238)
#include <fstream>
using namespace std;
ifstream fin ("barbar.in");
ofstream fout ("barbar.out");
const int N = 1005;
int n, m, stc, drc;
int nr, l, c, dist[N][N], L, C, LF, CF;
char a[N][N]; //matricea citita
bool viz[N][N];
int dl[] = {-1, 0, 0, 1};
int dc[] = {0, -1, 1, 0};
struct punct {
int l, c, nr; //linia, coloana, distanta minima fata de oricare din dragoni
} q[N * N];
void reinit() {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
viz[i][j] = 0;
for (int i = 1; i <= drc; ++i)
q[i] = {0, 0, 0};
stc = 0, drc = 0;
}
bool bfs(int k) { //distanta minima pe care ma pot deplasa
reinit(); //reinitializez viz si coada
q[1] = {L, C, 0};
stc = drc = 1;
viz[L][C] = true;
while (stc <= drc) {
l = q[stc].l;
c = q[stc].c;
++stc;
for (int i = 0; i < 4; ++i) {
if (l + dl[i] == 0 || c + dc[i] == 0 || l + dl[i] > n || c + dc[i] > m); //verific daca ies din matrice
else {
if (a[l + dl[i]][c + dc[i]] != '*' //pozitia (l + dl[i], c + dc[i]) nu este perete
&& !viz[l + dl[i]][c + dc[i]] //si nu a fost vizitata inca
&& dist[l + dl[i]][c + dc[i]] >= k) //si este 'accesibila', adica nu are distanta fata de un dragon mai mica decat k
{
q[++drc] = {l + dl[i], c + dc[i], 0}; //il bag pe (l + dl[i], c + dc[i]) in coada
viz[l + dl[i]][c + dc[i]] = true; //si il marchez ca vizitat
}
}
}
}
if (viz[LF][CF])
return true;
return false;
}
int main() {
fin >> n >> m; //citesc dimensiunile matricii
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
fin >> a[i][j]; //citesc matricea
if (a[i][j] == 'D') {
q[++drc] = {i, j, 0}; //introduc in coada coordonatele dragonului
//si distanta lui minima fata de oricare din dragoni (0)
}
if (a[i][j] == 'I')
L = i, C = j; //retin coordonatele punctului de start
if (a[i][j] == 'O')
LF = i, CF = j; //retin coordonatele punctului de finish
}
}
stc = 1;
while (stc <= drc) {
l = q[stc].l;
c = q[stc].c;
nr = q[stc].nr;
++stc;
for (int i = 0; i < 4; ++i) { //parcurg vecinii elementului
if (l + dl[i] == 0 || c + dc[i] == 0 || l + dl[i] > n || c + dc[i] > m); //verific daca ies din matrice
else if (dist[l + dl[i]][c + dc[i]] == 0 && a[l + dl[i]][c + dc[i]] != 'D') { //verific daca nu am mai trecut elementul (l + dl[i], c + dc[i])
q[++drc] = {l + dl[i], c + dc[i], nr + 1}; //il introduc in coada
dist[l + dl[i]][c + dc[i]] = nr + 1;
}
}
}
//acum dist[i][j] = distanta minima de la (i, j) fata de cel mai apropiat dragon de el
int st = 0, dr = dist[LF][CF], mij, ans = -1;
while (st <= dr) { //caut binar valoarea minima din dist pe care ma voi deplasa
mij = (st + dr) / 2;
if (bfs(mij)) { //verific daca pot ajunge de la start la finish mergand numai pe valori >= cu mij
ans = mij;
st = mij + 1;
} else
dr = mij - 1;
}
fout << ans;
return 0;
}