Pagini recente » Cod sursa (job #469616) | Cod sursa (job #91124) | Cod sursa (job #2441899) | Cod sursa (job #1700025) | Cod sursa (job #2163965)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define dimm 1005
#define y first
#define x second
const int mval = 100000;
std::ifstream f("barbar.in");
std::ofstream g("barbar.out");
int N, M;
int y0, y, x0, x;
char vis[dimm][dimm]; //matricea citita
int danger[dimm][dimm]; //folosim la lee cu dragoni
std::queue <std::pair <int, int>> dragon; //din nou la lee cu dragoni
void precalc() {
for (int i=0, j; i<=N+1; i++)
for (j=0; j<=M+1; j++)
danger[i][j] = mval;
}
void citire() {
f >> N >> M;
char ch;
for (int i=0, j; i<N; i++)
for (j=0; j<M; j++) {
f >> vis[i+1][j+1];
ch = vis[i+1][j+1];
if(ch=='.');
else if(ch=='*');
else if(ch=='D')
dragon.push(std::pair <int, int> (i+1, j+1)), danger[i+1][j+1] = 0;
else if(ch=='I') y0=i+1, x0=j+1;
else y=i+1, x=j+1;
}
}
int dx[] = {1, -1, 0, 0}, dy[]= {0, 0, 1, -1};
typedef std::pair <int, int> nod;
void lee_danger() {
nod pres, nou;
bool vizd[dimm][dimm];
for (int i=1, j; i<=N; i++) for (j=1; j<=M; j++) vizd[i][j] = 0;
while(!dragon.empty()) {
pres = dragon.front();
dragon.pop();
for (int i=0; i<4; i++) {
nou = pres;
nou.y += dy[i], nou.x += dx[i];
if(nou.y < 1 || nou.x < 1 || nou.y > N || nou.x > M)
continue;
if(vis[nou.y][nou.x] == '.')
if(!vizd[nou.y][nou.x]) {
danger[nou.y][nou.x] = danger[pres.y][pres.x] + 1, dragon.push(nou);
vizd[nou.y][nou.x] = 1;
}
}
}
}
bool viz[dimm][dimm];
bool lee(int capacitate) {
for (int i=1, j; i<=N; i++)
for (j=1; j<=M; j++)
viz[i][j] = 0;
std::queue <nod> q;
q.push({y0, x0});
nod pres, nou;
while(!q.empty()) {
pres = q.front();
q.pop();
for(int i=0; i<4; i++) {
nod nou = pres;
nou.y += dy[i]; nou.x += dx[i];
if(nou.y < 1 || nou.x < 1 || nou.y > N || nou.x > M)
continue;
if(nou.y == y && nou.x == x)
return true;
if(!viz[nou.y][nou.x] && vis[nou.y][nou.x] == '.' && danger[nou.y][nou.x] >= capacitate)
viz[nou.y][nou.x] = 1, q.push(nou);
}
} return false;
}
void rezolvare() {
lee_danger();
int st=0, dr=10*dimm, rez=-1, m;
while(st<=dr) {
m = (st+dr)/2;
if(!lee(m)) dr=m-1;
else rez = std::max(rez, m), st=m+1;
}
g << rez;
}
int main()
{
precalc();
citire();
rezolvare();
return 0;
}