Pagini recente » Cod sursa (job #3017129) | Cod sursa (job #2963856) | Cod sursa (job #2952568) | Cod sursa (job #2968082) | Cod sursa (job #851556)
Cod sursa(job #851556)
//ideea ii asa: fac un bfs in care sa am initial in coada toate nodurile cu dragoni
//si calculez dist[i][j] = distanta pana la cel mai apropiat dragon
//apoi, trebuie sa gasesc cea mai mare distanta X
//pentru care sa pot ajunge de la I la O doar prin casute cu valori >= X
//ca sa gasesc eficient valoarea asta, o caut binar, si la fiecare pas fac un bfs (incerc sa ajung de la I la O)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <deque>
#include <queue>
#include <stack>
#define nmax 1005
#define x first
#define y second
#define inf 1<<30
using namespace std;
struct nod {
int x, y;
};
queue <nod> q;
char a[nmax][nmax];
bool vizitat[nmax][nmax], posibil, exista_vreo_solutie = false;
int dist[nmax][nmax];
vector <nod> ind;
int i, j, r, c, st, dr, distanta;
nod start, finish;
void init() {
for(int i=1; i<=r; i++)
for(int j=1; j<=c; j++)
vizitat[i][j] = false;
}
bool valid(nod z) {
if(z.x >= 1 && z.x <= r && z.y >= 1 && z.y <= c)
if(a[z.x][z.y] != '*') return true;
return false;
}
void bfs_distanta() {
nod curent, vecin;
while(!q.empty()) {
curent = q.front();
vizitat[curent.x][curent.y] = true;
q.pop();
for(int i=0; i<ind.size(); i++) {
vecin.x = curent.x + ind[i].x;
vecin.y = curent.y + ind[i].y;
if(valid(vecin) && !vizitat[vecin.x][vecin.y]) {
dist[vecin.x][vecin.y] = min(dist[vecin.x][vecin.y], dist[curent.x][curent.y] + 1);
q.push(vecin);
vizitat[vecin.x][vecin.y] = true;
}
}
}
}
void bfs(int distanta) {
nod curent, vecin;
while(!q.empty()) {
curent = q.front();
vizitat[curent.x][curent.y] = true;
q.pop();
if(curent.x == finish.x && curent.y == finish.y) {
posibil = true;
exista_vreo_solutie = true;
while(!q.empty()) q.pop();
}
for(int i=0; i<ind.size(); i++) {
vecin.x = curent.x + ind[i].x;
vecin.y = curent.y + ind[i].y;
if(valid(vecin) && !vizitat[vecin.x][vecin.y] && dist[vecin.x][vecin.y] >= distanta) {
q.push(vecin);
vizitat[vecin.x][vecin.y] = true;
}
}
}
}
int main() {
ifstream f("barbar.in");
ofstream g("barbar.out");
nod z;
for(i=-1; i<=1; i++)
for(j=-1; j<=1; j++)
if(abs(i) != abs(j)) { z.x = i; z.y = j; ind.push_back(z); }
f>>r>>c;
for(i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
f>>a[i][j];
dist[i][j] = inf;
if(a[i][j] == 'I') start.x = i, start.y = j;
if(a[i][j] == 'O') finish.x = i, finish.y = j;
if(a[i][j] == 'D') z.x = i, z.y = j, q.push(z), dist[i][j] = 0;
}
}
init();
bfs_distanta();
/*for(i=1; i<=r; i++) {
for(j=1; j<=c; j++) {
if(dist[i][j]==inf) g<<"* ";
else g<<dist[i][j]<<" ";
}
g<<"\n";
}*/
while(!q.empty()) q.pop();
st = -1;
dr = nmax + nmax - 1;
while(dr - st > 1) {
distanta = (st + dr) / 2;
posibil = false;
init();
q.push(start); //bag nodul initial in coada
bfs(distanta);
if(posibil) st = distanta;
else dr = distanta;
}
if(!exista_vreo_solutie) st = -1;
g<<st<<"\n";
cout<<st<<"\n";
return 0;
}