Pagini recente » Monitorul de evaluare | Cod sursa (job #238124) | Cod sursa (job #1229566) | Cod sursa (job #968190) | Cod sursa (job #3326657)
#include <iostream>
#include <fstream>
#include <queue>
#include <string>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int R, C;
int distD[1002][1002]; // distanta pana la cel mai apropiat dragon
int dl[] = {0, 0, 1, -1};
int dc[] = {-1, 1, 0, 0};
queue<pair<int,int>> q;
string linie;
bool valid(int x, int y)
{
return (x >= 0 && x < R && y >= 0 && y < C);
}
void lee_dragoni()
{
while (!q.empty())
{
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int d = 0; d < 4; d++)
{
int nx = x + dl[d];
int ny = y + dc[d];
if (valid(nx, ny))
{
if (distD[nx][ny] == -1) // celula libera nevizitata
{
distD[nx][ny] = distD[x][y] + 1;
q.push({nx, ny});
}
}
}
}
}
int start_x, start_y, exit_x, exit_y;
// verifica daca exista drum de la I la O cu distanta minima >= val
bool exista_drum(int val)
{
if (distD[start_x][start_y] < val)
return false;
static int viz[1002][1002];
for (int i = 0; i < R; i++)
for (int j = 0; j < C; j++)
viz[i][j] = 0;
queue<pair<int,int>> coada;
coada.push({start_x, start_y});
viz[start_x][start_y] = 1;
while (!coada.empty())
{
int x = coada.front().first;
int y = coada.front().second;
coada.pop();
if (x == exit_x && y == exit_y)
return true;
for (int d = 0; d < 4; d++)
{
int nx = x + dl[d];
int ny = y + dc[d];
if (valid(nx, ny) && !viz[nx][ny])
{
if (distD[nx][ny] >= val)
{
viz[nx][ny] = 1;
coada.push({nx, ny});
}
}
}
}
return false;
}
int main()
{
fin >> R >> C;
// citim gridul ca stringuri
vector<string> grid(R);
for (int i = 0; i < R; i++)
fin >> grid[i];
// initializam distanta la -2 pentru pereti, -1 pentru celule libere
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
if (grid[i][j] == '*')
distD[i][j] = -2; // perete
else
distD[i][j] = -1; // vizitabil
if (grid[i][j] == 'D')
{
distD[i][j] = 0; // dragon = 0
q.push({i, j}); // multi-sursa
}
if (grid[i][j] == 'I')
{
start_x = i;
start_y = j;
}
if (grid[i][j] == 'O')
{
exit_x = i;
exit_y = j;
}
}
}
// LEE de la dragoni → calculeaza distanta pana la cel mai apropiat dragon
lee_dragoni();
// cautare binara pe distanta minima ceruta
int st = 0, dr = R + C, ans = -1;
while (st <= dr)
{
int mid = (st + dr) / 2;
if (exista_drum(mid))
{
ans = mid;
st = mid + 1;
}
else
{
dr = mid - 1;
}
}
fout << ans;
return 0;
}