Cod sursa(job #2767538)

Utilizator AlexZeuVasile Alexandru AlexZeu Data 6 august 2021 16:42:16
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <bits/stdc++.h>
using namespace std;

const int mxN = 1e3 + 5, INF = 1e9 + 7;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

int n, m, nearest_dragon[mxN][mxN], best_choice[mxN][mxN], finish_line, finish_col, start_line, start_col;
char mt[mxN][mxN];
queue<pair<int, int>> dragons;
set<pair<int, pair<int, int>>> s;

bool valid(int line, int col) {
    return (line >= 1 && line <= n && col >= 1 && col <= m && mt[line][col] != '*' && mt[line][col] != 'D');
}

vector<pair<int, int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

void bfs_dragons() {
    while (!dragons.empty()) {
        int curr_line = dragons.front().first;
        int curr_col = dragons.front().second;
        dragons.pop();
        for (pair<int, int> dir : directions) {
            int new_line = curr_line + dir.first;
            int new_col = curr_col + dir.second;
            if (valid(new_line, new_col) && nearest_dragon[new_line][new_col] > nearest_dragon[curr_line][curr_col] + 1) {
                nearest_dragon[new_line][new_col] = nearest_dragon[curr_line][curr_col] + 1;
                dragons.push({new_line, new_col});
            }
        }
    }
}

void barbar() {
    best_choice[start_line][start_col] = nearest_dragon[start_line][start_col];
    s.insert({best_choice[start_line][start_col], {start_line, start_col}});
    while (!s.empty()) {
        int curr_line = s.rbegin()->second.first;
        int curr_col = s.rbegin()->second.second;
        s.erase(prev(s.end()));
        for (pair<int, int> dir : directions) {
            int new_line = curr_line + dir.first;
            int new_col = curr_col + dir.second;
            if (valid(new_line, new_col) && best_choice[new_line][new_col] < min(best_choice[curr_line][curr_col], nearest_dragon[new_line][new_col])) {
                if (best_choice[new_line][new_col] != 0) {
                    s.erase(s.find({best_choice[new_line][new_col], {new_line, new_col}}));
                }
                best_choice[new_line][new_col] = min(best_choice[curr_line][curr_col], nearest_dragon[new_line][new_col]);
                s.insert({best_choice[new_line][new_col], {new_line, new_col}});
            }
        }
    }
}

void solve() {
    fin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            fin >> mt[i][j];
            best_choice[i][j] = 0;
            nearest_dragon[i][j] = INF;
            if (mt[i][j] == 'D') {
                dragons.push({i, j});
                nearest_dragon[i][j] = 0;
            } else if (mt[i][j] == 'I') {
                start_line = i;
                start_col = j;
            } else if (mt[i][j] == 'O') {
                finish_line = i;
                finish_col = j;
            }
        }
    }
    bfs_dragons();
    barbar();
    fout << (best_choice[finish_line][finish_col] == 0 ? -1 : best_choice[finish_line][finish_col]);
}

int main() {
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

//read the question correctly (ll vs int)
//what's the meaning of the problem ? Think outside the BOX !!!
//edge cases ?
//make it simple
//write everything (observations, edge cases, ideas, steps, methods, ...)