Pagini recente » Cod sursa (job #2821992) | Cod sursa (job #3276544) | Cod sursa (job #789534) | Cod sursa (job #2682907) | Cod sursa (job #3352787)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
int n, m;
vector<vector<char>> mat;
pair<int, int> startPos, endPos;
vector<vector<int>> dist;
vector<int> dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
bool in_mat(int i, int j) {
return i >= 1 && i <= n && j >= 1 && j <= m;
}
// calculam pentru fiecare celula distanta pana la cel mai apropiat dragon
void dragonsDistances() {
dist.resize(n + 1, vector<int>(m + 1, -1));
queue<pair<int, int>> q;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (mat[i][j] == 'D') {
dist[i][j] = 0;
q.push({i, j});
}
}
}
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i) {
int next_x = x + dx[i];
int next_y = y + dy[i];
if (in_mat(next_x, next_y) && mat[next_x][next_y] != '*' && dist[next_x][next_y] == -1) {
dist[next_x][next_y] = dist[x][y] + 1;
q.push({next_x, next_y});
}
}
}
}
// verificam daca exista un drum de la 'I' la 'O' in care cel mai apropiat dragon sa fie la distanta k
bool canReach(int k) {
if (dist[startPos.first][startPos.second] < k || dist[endPos.first][endPos.second] < k)
return false;
vector<vector<bool>> visited(n + 1, vector<bool>(m + 1));
queue<pair<int, int>> q;
q.push(startPos);
while (!q.empty()) {
if (q.front() == endPos)
return true;
int x = q.front().first;
int y = q.front().second;
q.pop();
for (int i = 0; i < 4; ++i) {
int next_x = x + dx[i];
int next_y = y + dy[i];
if (in_mat(next_x, next_y) && !visited[next_x][next_y] && mat[next_x][next_y] != '*' && dist[next_x][next_y] >= k) {
visited[next_x][next_y] = true;
q.push({next_x, next_y});
}
}
}
return false;
}
int main() {
ifstream fin("barbar.in");
ofstream fout("barbar.out");
fin >> n >> m;
mat.resize(n + 1, vector<char>(m + 1));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
fin >> mat[i][j];
if (mat[i][j] == 'I')
startPos = {i, j};
if (mat[i][j] == 'O')
endPos = {i, j};
}
}
dragonsDistances();
int ans = -1, left = 0, right = n + m;
while (left <= right) {
int mid = left + (right - left) / 2;
if (!canReach(mid))
right = mid - 1;
else {
ans = mid;
left = mid + 1;
}
}
fout << ans;
return 0;
}