Cod sursa(job #2769293)

Utilizator Andrei_TudorAndrei Tudor Andrei_Tudor Data 14 august 2021 16:02:32
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.63 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream cin("barbar.in");
ofstream cout("barbar.out");

char a[1005][1005];
int dist[1005][1005];
int m[1005][1005];

void dragonlee(int r, int c, vector <pair <int, int>> v){
    const int dirx[] = {0, 0, 1, -1};
    const int diry[] = {1, -1, 0, 0};
    queue <pair <int, int>> Q;
    for(auto elem : v){
        Q.push(elem);
        dist[elem.first][elem.second] = 0;
    }
    auto inside = [&r, &c](const pair <int, int>& cell) -> bool {
        return 1 <= cell.first && cell.first <= r && 1 <= cell.second && cell.second <= c;
    };
    while(!Q.empty()){
        auto cell = Q.front();
        Q.pop();
        for(int dir = 0; dir <= 3; dir ++){
            pair <int, int> x = make_pair(cell.first + dirx[dir], cell.second + diry[dir]);
            if(!inside(x) || a[x.first][x.second] == '*'){
                continue;
            }
            else if(dist[x.first][x.second] == 0){
                dist[x.first][x.second] = dist[cell.first][cell.second] + 1;
                Q.push(x);
            }
        }
    }
    // cout << inside(make_pair(r, c)) << "\n";
    /*cout << inside([0, 1]) << "\n";
    cout << inside([1, 0]) << "\n";
    cout << inside([0, 0]) << "\n";*/
}

void lee(pair <int, int> start, int k, int r, int c){
    const int dirx[] = {0, 0, 1, -1};
    const int diry[] = {1, -1, 0, 0};
    queue <pair <int, int>> Q;
    Q.push(start);
    auto inside = [&r, &c](const pair <int, int>& cell) -> bool {
        return 1 <= cell.first && cell.first <= r && 1 <= cell.second && cell.second <= c;
    };
    m[start.first][start.second] = 1;
    while(!Q.empty()){
        auto cell = Q.front();
        Q.pop();
        for(int dir = 0; dir <= 3; dir ++){
            pair <int, int> x = make_pair(cell.first + dirx[dir], cell.second + diry[dir]);
            if(!inside(x) || a[x.first][x.second] == '*' || dist[x.first][x.second] < k){
                continue;
            }
            else if(m[x.first][x.second] == 0){
                m[x.first][x.second] = m[cell.first][cell.second] + 1;
                Q.push(x);
            }
        }
    }
    // cout << inside(make_pair(r, c)) << "\n";
    /*cout << inside([0, 1]) << "\n";
    cout << inside([1, 0]) << "\n";
    cout << inside([0, 0]) << "\n";*/
}

void reset(int r, int c){
    for(int i = 1; i <= r; i ++){
        for(int j = 1; j <= c; j ++){
            m[i][j] = 0;
        }
    }
}

int main(){
    int r, c;
    cin >> r >> c;
    cin.get();
    char ch;
    vector <pair <int, int>> v;
    pair <int, int> start;
    pair <int, int> end;
    for(int i = 1; i <= r; i ++){
        for(int j = 1; j <= c; j ++){
            ch = cin.get();
            if(ch == '\n'){
                break;
            }
            a[i][j] = ch;
            if(a[i][j] == 'D'){
                v.push_back({i, j});
            }
            else if(a[i][j] == 'I'){
                start.first = i;
                start.second = j;
            }
            else if(a[i][j] == 'O'){
                end.first = i;
                end.second = j;
            }
        }
        cin.get();
    }
    dragonlee(r, c, v);
    for(auto elem : v){
        dist[elem.first][elem.second] = 0;
    }
    int st = 0, dr = max(r, c), sol = -1;
    while(st <= dr){
        int mij = (st + dr) / 2;
        reset(r, c);
        lee(start, mij, r, c);
        if(m[end.first][end.second] > 0){
            st = mij + 1;
            sol = mij;
        }
        else {
            dr = mij - 1;
        }
    }
    cout << sol;
}