Cod sursa(job #2866771)

Utilizator Theodor17Pirnog Theodor Ioan Theodor17 Data 9 martie 2022 22:56:33
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <bitset>
#include <queue>

using namespace std;

ifstream cin("barbar.in");
ofstream cout("barbar.out");

const int NMAX = 1e3;
const int dl[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
queue <pair <int, int>> q;
int dmin_dragon[NMAX][NMAX], n, m;
pair <int, int> start, leave;

void read(){

    cin >> n >> m;

    char ch;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){

            cin >> ch;
            if(ch == 'D'){

                q.push({i, j});
                dmin_dragon[i][j] = 1;

            }
            else if(ch == '*')
                dmin_dragon[i][j] = -1;
            else if(ch == 'I')
                start = {i, j};
            else if(ch == 'O')
                leave = {i, j};

        }
    }

}

bool inside(int x, int y){
    return(x < n && x >= 0 && y < m && y >= 0);
}

void dragon(){

    while(!q.empty()){

        int f1 = q.front().first;
        int f2 = q.front().second;

        for(int k = 0; k < 4; k++){

            int iv = f1 + dl[k];
            int jv = f2 + dc[k];

            if(inside(iv, jv) && dmin_dragon[iv][jv] != -1 && (!dmin_dragon[iv][jv] || dmin_dragon[iv][jv] > dmin_dragon[f1][f2] + 1)){

                dmin_dragon[iv][jv] = dmin_dragon[f1][f2] + 1;
                q.push({iv, jv});


            }
        }

        q.pop();
    }

}

bool valid(int dist){

    bitset <NMAX> seen[NMAX];
    seen[start.first][start.second] = 1;
    q.push(start);

    while(!q.empty()){

        int f1 = q.front().first;
        int f2 = q.front().second;

        for(int k = 0; k < 4; k++){

            int iv = f1 + dl[k];
            int jv = f2 + dc[k];

            if(inside(iv, jv) && dmin_dragon[iv][jv] != -1 && !seen[iv][jv] && dmin_dragon[iv][jv] >= dist){

                // dmin_dragon[iv][jv] = distanta minima la care se afla un dragon fata de celula (iv, jv)
                // daca un dragon se afla mai departe decat distanta pe care am presupus o ca fiind MINIMA, atunci nu ma afecteaza

                seen[iv][jv] = 1;
                q.push({iv, jv});

            }

        }

        q.pop();
    }

    return seen[leave.first][leave.second];
}

int bin_search(){

    int st = 0, dr = 1e9;
    int ans = 0, mid = 0;

    while(st <= dr){

        // presupun ca mid este distanta cea mai mica la care un dragon se afla pe parcursul unui traseu
        mid = ((st + dr) >> 1);

        if(valid(mid)){

            ans = mid;
            st = mid + 1;

        }else dr = mid - 1;

    }

    return --ans;
}

int main(){

    read();
    dragon();
    cout << bin_search();

    return 0;
}