Cod sursa(job #3002024)

Utilizator andreea_chivuAndreea Chivu andreea_chivu Data 14 martie 2023 11:40:16
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;

const int NMAX = 1005;

struct punct{
    int lin, col;
};

int dl[] = {-1, 0, 1, 0};
int dc[] = {0, 1, 0, -1};
punct xi, xf;
int nl, nc;

int dd[NMAX][NMAX]; // distante de la dragoni
bool accesibil[NMAX][NMAX];

bool ajung(int dist){
    if(dd[xi.lin][xi.col] < dist)
        return false;
    for(int i = 1; i <= nl; i++){
        for(int j = 1; j <= nc; j++){
            accesibil[i][j] = true;
            if(dd[i][j] < dist)
                accesibil[i][j] = false;
        }
    }
    queue <punct> q;
    q.push(xi);
    while(!q.empty()){
        punct x = q.front();
        q.pop();
        for(int i = 0; i < 4; i++){
            punct y;
            y.lin = x.lin + dl[i];
            y.col = x.col + dc[i];
            if(accesibil[y.lin][y.col]){
                if(y.lin == xf.lin && y.col == xf.col)
                    return true;
                q.push(y);
                accesibil[y.lin][y.col] = false;
            }
        }
    }
    return false;
}

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

    fin >> nl >> nc;

    //bordare
    for(int i = 0; i <= nl + 1; i++){
        dd[i][0] = dd[i][nc+1] = -2;
    }
    for(int i = 0; i <= nc + 1; i++){
        dd[0][i] = dd[nl+1][i] = -2;
    }


    //citire
    queue <punct> q;

    for(int i = 1; i <= nl; i++){
        string s;

        fin >> s;

        for(int j = 0; j < nc; j++){
            if(s[j] == '.'){
                dd[i][j+1] = -1;
            }else if(s[j] == 'D'){
                dd[i][j+1] = 0;
                punct x;
                x.lin = i;
                x.col = j+1;
                q.push(x);
            }else if(s[j] == 'I'){
                dd[i][j+1] = -1;
                xi.lin = i;
                xi.col = j+1;
            }else if(s[j] == 'O'){
                dd[i][j+1] = -1;
                xf.lin = i;
                xf.col = j+1;
            }else if(s[j] == '*'){
                dd[i][j+1] = -2;
            }
        }
    }

    //distantele minime din fiecare pozitie pana la dragoni

    while(!q.empty()){
        punct x = q.front();
        q.pop();
        for(int i = 0; i < 4; i++){
            punct y;
            y.lin = x.lin + dl[i];
            y.col = x.col + dc[i];
            if(dd[y.lin][y.col] == -1){
                dd[y.lin][y.col] = dd[x.lin][x.col] + 1;
                q.push(y);
            }
        }
    }

    //fac cautare binara de distanta minima

    int st = 0;
    int dr = nl * nc;
    int rez = -1;
    while(st <= dr){
        int m = (st + dr) / 2;
        if(ajung(m)){
            rez = m;
            st = m + 1;
        }else{
            dr = m - 1;
        }
    }

    fout << rez;


    fin.close();
    fout.close();
    return 0;
}