Nu aveti permisiuni pentru a descarca fisierul grader_test16.in
Cod sursa(job #2075976)
Utilizator | Data | 25 noiembrie 2017 21:45:38 | |
---|---|---|---|
Problema | Barbar | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 3.36 kb |
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
const int MAX_N = 1005;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int n, m;
bool visited[MAX_N][MAX_N];
bool walls[MAX_N][MAX_N];
int dragon_dist[MAX_N][MAX_N];
inline bool in(int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m;
}
bool CanTravel(int dist, std::pair<int, int> start, std::pair<int, int> stop) {
if (dragon_dist[start.first][start.second] < dist) {
return false;
}
std::queue< std::pair<int, int> > q;
memset(visited, 0, sizeof visited);
q.push(start);
visited[start.first][start.second] = true;
while (!q.empty()) {
auto pos = q.front();
q.pop();
for (int d = 0; d < 4; ++ d) {
std::pair<int, int> new_pos = {pos.first + dx[d], pos.second + dy[d]};
if (0 > new_pos.first || n <= new_pos.first || 0 > new_pos.second || m <= new_pos.second) {
continue;
}
if (!visited[new_pos.first][new_pos.second] && !walls[new_pos.first][new_pos.second] && dragon_dist[new_pos.first][new_pos.second] >= dist) {
if (new_pos == stop) {
return true;
}
visited[new_pos.first][new_pos.second] = true;
q.push(new_pos);
}
}
}
return false;
}
void bfs(const std::vector< std::pair<int, int> > &dragons) {
}
int main()
{
std::ifstream cin("barbar.in");
std::ofstream cout("barbar.out");
char line[MAX_N];
cin >> n >> m;
std::pair<int, int> start, stop;
std::queue< std::pair<int, int> > q;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
dragon_dist[i][j] = 1000000000;
}
}
for (int i = 0; i < n; ++ i) {
cin >> line;
for (int j = 0; j < m; ++ j) {
if (line[j] == '.') {
continue;
}
if (line[j] == 'D') {
dragon_dist[i][j] = 0;
q.push({i, j});
continue;
}
if (line[j] == '*') {
walls[i][j] = true;
continue;
}
if (line[j] == 'I') {
start = {i, j};
} else {
stop = {i, j};
}
}
}
while (!q.empty()) {
auto pos = q.front();
q.pop();
for (int d = 0; d < 4; ++ d) {
std::pair<int, int> new_pos = {pos.first + dx[d], pos.second + dy[d]};
if (0 > new_pos.first || n <= new_pos.first || 0 > new_pos.second || m <= new_pos.second) {
continue;
}
if (dragon_dist[new_pos.first][new_pos.second] == 1000000000 && !walls[new_pos.first][new_pos.second]) {
dragon_dist[new_pos.first][new_pos.second] = dragon_dist[pos.first][pos.second] + 1;
q.push(new_pos);
}
}
}
int left = 0, right = n * m, best = -1;
while (left <= right) {
int middle = (left + right) / 2;
if (CanTravel(middle, start, stop)) {
best = middle;
left = middle + 1;
} else {
right = middle - 1;
}
}
cout << best << "\n";
return 0;
}