Mai intai trebuie sa te autentifici.
Cod sursa(job #2017404)
Utilizator | Data | 1 septembrie 2017 07:21:04 | |
---|---|---|---|
Problema | Barbar | Scor | 90 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 3.44 kb |
#include <fstream>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");
const int INF = 2e9;
const int MAX = 1005;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
bool walled[MAX][MAX];
int dist_drag[MAX][MAX];
bool used[MAX][MAX];
/*vector < vector < bool > > walled(MAX, vector < bool > (MAX));
vector < vector < int > > dist_drag(MAX, vector < int > (MAX, INF));
vector < vector < bool > > used(MAX, vector < bool > (MAX));*/
void init(int n, int m) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
dist_drag[i][j] = INF;
}
}
}
bool is_good(int i, int j, int n, int m) {
return i >= 1 and j >= 1 and i <= n and j <= m;
}
void read(int n, int m, pair < int, int > &me, pair < int, int > &dest, queue < pair < int, int > > &drags) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
char c;
cin >> c;
if (c == 'I') {
me = {i, j};
}
else if (c == 'O') {
dest = {i, j};
}
else if (c == 'D') {
drags.push({i, j});
}
else if (c == '*') {
walled[i][j] = true;
}
}
}
}
void complete (pair < int, int > dragon, int n, int m, int &pure_max_dist) {
queue < pair < int, int > > q;
dist_drag [dragon.first][dragon.second] = 0;
walled[dragon.first][dragon.second] = true;
q.push(dragon);
while (!q.empty()) {
auto cur = q.front();
q.pop();
for (int i = 0; i < 4; i ++) {
int row = cur.first + di[i];
int col = cur.second + dj[i];
if (!is_good(row, col, n, m)) continue;
if (walled[row][col]) continue;
if (dist_drag[row][col] <= dist_drag[cur.first][cur.second] + 1) continue;
dist_drag[row][col] = dist_drag[cur.first][cur.second] + 1;
pure_max_dist = max (pure_max_dist, dist_drag[row][col]);
q.push({row, col});
}
}
}
void reset(int n, int m) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= m; j ++) {
used[i][j] = false;
}
}
}
bool found_path(int min_dist, pair < int, int > me, pair < int, int > dest, int n, int m) {
reset(n, m);
queue < pair < int, int > > q;
if (dist_drag[me.first][me.second] >= min_dist) {
q.push(me);
used[me.first][me.second] = true;
}
while (!q.empty()) {
auto cur = q.front();
q.pop();
for (int i = 0; i < 4; i ++) {
int row = cur.first + di[i];
int col = cur.second + dj[i];
if (used[row][col])continue;
if (!is_good(row, col, n, m)) continue;
if (walled[row][col]) continue;
if (dist_drag[row][col] < min_dist) continue;
if (dest == make_pair(row, col)) return true;
used[row][col] = true;
q.push({row, col});
}
}
return false;
}
int main(int argc, char const *argv[]) {
int n, m;
cin >> n >> m;
init(n ,m);
queue < pair < int, int > > drags;
pair < int, int > me;
pair < int, int > dest;
read(n , m, me, dest, drags);
int pure_max_dist = -1;
while (!drags.empty()) {
complete(drags.front(), n, m, pure_max_dist);
drags.pop();
}
int sol = -1;
int ans = 0;
for (int bit = log2(n + m + 1); bit >= 0; bit --) {
if ((1 << bit) > n + m + 1) continue;
if ((1 << bit) > pure_max_dist) continue;
if (found_path(ans + (1 << bit), me, dest, n, m)) {
ans += (1 << bit);
sol = ans;
}
}
cout << sol << '\n';
return 0;
}