Cod sursa(job #2763884)

Utilizator EusebiudistrugatorulLionel Messi Eusebiudistrugatorul Data 17 iulie 2021 15:31:29
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.87 kb
#include <bits/stdc++.h>
#define Intro ios::sync_with_stdio(0), cin.tie(0)
#define ll long long
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int prison[1003][1003], dist[1003][1003], max_dist[1003][1003], rows, columns;
bool visited[1003][1003];
int start_row, start_col, finish_row, finish_col;
vector<pair<int, int>> dragon_places;

void find_dist() {
    queue<pair<int, int>> nodes;
    for (auto itr : dragon_places) {
        nodes.push({itr.first, itr.second});
    }
    while (!nodes.empty()) {
        auto itr = nodes.front();
        int main_row = itr.first;
        int main_col = itr.second;
        nodes.pop();
        int dir_row[] = {1, 0, -1, 0}, dir_col[] = {0, 1, 0, -1};
        for (int i = 0; i < 4; ++i) {
            int curr_row = main_row + dir_row[i];
            int curr_col = main_col + dir_col[i];
            if (curr_col > columns or curr_col < 1 or curr_row > rows or curr_row < 1 or prison[curr_row][curr_col] != 0) {
                continue;
            }
            if (!visited[curr_row][curr_col]) {
                dist[curr_row][curr_col] = dist[main_row][main_col] + 1;
                visited[curr_row][curr_col] = true;
                nodes.push({curr_row, curr_col});
            }
        }
    }
}

int find_max_dist() {
    set<pair<int, pair<int, int>>> ordered_dist;
    ordered_dist.insert({dist[start_row][start_col], {start_row, start_col}});
    max_dist[start_row][start_col] = dist[start_row][start_col];
    while (!ordered_dist.empty()) {
        auto itr = ordered_dist.end();
        itr--;
        int main_row = itr->second.first, main_col = itr->second.second;
        if (main_row == finish_row and main_col == finish_col) {
            return max_dist[finish_row][finish_col];
        }
        ordered_dist.erase(itr);
        int dir_row[] = {1, 0, -1, 0}, dir_col[] = {0, 1, 0, -1};
        for (int i = 0; i < 4; ++i) {
            int curr_row = main_row + dir_row[i];
            int curr_col = main_col + dir_col[i];
            if (curr_col > columns or curr_col < 1 or curr_row > rows or curr_row < 1 or prison[curr_row][curr_col] != 0) {
                continue;
            }
            if (!visited[curr_row][curr_col]) {
                max_dist[curr_row][curr_col] = min(dist[curr_row][curr_col], max_dist[main_row][main_col]);
                visited[curr_row][curr_col] = true;
                ordered_dist.insert({max_dist[curr_row][curr_col], {curr_row, curr_col}});
            } else if (max_dist[curr_row][curr_col] < min(max_dist[main_row][main_col], dist[curr_row][curr_col])) {
                ordered_dist.erase(ordered_dist.find({max_dist[curr_row][curr_col], {curr_row, curr_col}}));
                max_dist[curr_row][curr_col] = min(dist[curr_row][curr_col], max_dist[main_row][main_col]);
                ordered_dist.insert({max_dist[curr_row][curr_col], {curr_row, curr_col}});
            }
        }
    }
    return -1;
}

int main() {
    fin >> rows >> columns;
    for (int i = 1; i <= rows; ++i) {
        for (int j = 1; j <= columns; ++j) {
            char c;
            fin >> c;
            if (c == '.') {
                prison[i][j] = 0;
            } else if (c == '*') {
                prison[i][j] = -1;
            } else if (c == 'D') {
                prison[i][j] = 1;
                dragon_places.push_back({i, j});
            } else if (c == 'I') {
                prison[i][j] = 0;
                start_row = i;
                start_col = j;
            } else {
                prison[i][j] = 0;
                finish_row = i;
                finish_col = j;
            }
        }
    }
    find_dist();
    for (int i = 1; i <= rows; ++i) {
        for (int j = 1; j <= columns; ++j) {
            visited[i][j] = false;
        }
    }
    fout << find_max_dist();
    return 0;
}