Cod sursa(job #3133918)

Utilizator Cyrex23Dumitrica Cezar Stefan Cyrex23 Data 27 mai 2023 15:25:16
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <fstream>
#include <queue>
using namespace std;

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

const int N = 1e3;

int dl[] = {-1, 0, 1, 0};
int dc[] = {0, -1, 0, 1};

struct poz{
    int l;
    int c;
};

queue <poz> q;

char a[N + 2][N + 2];
int d[N + 2][N + 2];
bool viz[N + 2][N + 2];
poz x_i, x_f;
int nl, nc;

void distante_dragoni(){
    while (!q.empty()){
        poz x = q.front();
        q.pop();
        for (int i = 0; i < 4; i++){
            poz y = (poz){x.l + dl[i], x.c + dc[i]};
            if (d[y.l][y.c] == -1){
                d[y.l][y.c] = 1 + d[x.l][x.c];
                q.push(y);
            }
        }
    }
}

bool exista_drum(int d_min)
{
    for (int i = 1; i <= nl; i++){
        for (int j = 1; j <= nc; j++){
            viz[i][j] = false;
            if (d[i][j] < d_min){
                viz[i][j] = true;
            }
        }
    }
    queue <poz> q;
    if (viz[x_i.l][x_i.c]){
        return false;
    }
    q.push(x_i);
    viz[x_i.l][x_i.c] = true;
    while (!q.empty()){
        poz x = q.front();
        q.pop();
        for (int i = 0; i < 4; i++){
            poz y = (poz){x.l + dl[i], x.c + dc[i]};
            if (!viz[y.l][y.c] && a[y.l][y.c] == '.'){
                q.push(y);
                viz[y.l][y.c] = true;
            }
            if (y.l == x_f.l && y.c == x_f.c){
                return true;
            }
        }
    }
    return false;
}

int caut_dist_max(){
    int st = 0, dr =  N * N, rez = - 1;
    while(st <= dr){
        int m = (st +  dr) / 2;
        if (exista_drum(m)){
            rez = m;
            st = m + 1;
        }
        else
            dr = m - 1;
    }
    return rez;
}

int main(){
    cin >> nl >> nc;
    for (int i = 1; i <= nl; i++)
    {
        cin >> a[i];
        for (int j = 1; j <= nc; j++)
        {
            if (a[i][j] == '.')
                d[i][j] = -1;
            else if (a[i][j] == '*')
                d[i][j] = -2;
            else if (a[i][j] == 'I'){
                d[i][j] = -1;
                x_i = (poz){i, j};
                a[i][j] = '.';
            }
            else if (a[i][j] == 'O'){
                d[i][j] = -1;
                x_f = (poz){i, j};
                a[i][j] = '.';
            }
            else{
                d[i][j] = 0;
                q.push((poz){i, j});
            }
        }
    }
    distante_dragoni();
    cout << caut_dist_max();
    return 0;
}