Cod sursa(job #3240456)

Utilizator PescarusTanislav Luca Andrei Pescarus Data 15 august 2024 16:54:56
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <fstream>
#include <queue>
#include <cstring>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
const int nmax = 1005;
char a[nmax][nmax];
int dist[nmax][nmax];
struct celula{
    int lin, col;
};
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
queue<celula> q, Q; //q pentru dragoni la inceput si Q pentru lee ul de dupa din binar
int r, c;
celula start;
bool isvalid(celula cell){
    return (cell.lin >= 1 && cell.lin <= r && cell.col >= 1 && cell.col <= c);
}
int sol;
int main(){
    f >> r >> c;
    for(int i = 1; i <= r; i++){
        for(int j = 1; j <= c; j++){
            f >> a[i][j];
            dist[i][j] = -1;
            if(a[i][j] == 'D'){
                dist[i][j] = 0;
                q.push({i, j});
            } else if(a[i][j] == 'I'){
                start = {i, j};
            }
        }
    }
    //facem lee din dragoni
    while(!q.empty()){
        celula cell = q.front();
        q.pop();
        for(int t = 0; t < 4; t++){
            celula vecin = {cell.lin + dx[t], cell.col + dy[t]};
            if(dist[vecin.lin][vecin.col] == -1 && a[vecin.lin][vecin.col] != '*'){
                dist[vecin.lin][vecin.col] = dist[cell.lin][cell.col] + 1;
                q.push(vecin);
            }
        }
    }
    //acum incepem cautarea binara
    int left = 0, right = r + c;
    while(left <= right){
        int mid = (left + right) / 2;
        //verificam daca exista un drum pentru mid
        //pe scurt facem iara lee
        bool ok = true; //daca putem ajunge
        bool amajuns = false; //daca ajung la destrinatie
        queue<celula> Q;
        Q.push(start);
        if(dist[start.lin][start.col] < mid){
            //nu mergem asa ca trecem la pasul urmator incercand un mid mai mic
            right = mid - 1;
            continue;
        }
        while(!Q.empty() && ok == true && amajuns == false){
            celula cell = Q.front();
            Q.pop();
            for(int t = 0; t < 4; t++){
                celula vecin = {cell.lin + dx[t], cell.col + dy[t]};
                if(isvalid(vecin) && dist[vecin.lin][vecin.col] >= mid && a[vecin.lin][vecin.col] != 'D' && a[vecin.lin][vecin.col] != '*'){
                    Q.push(vecin);
                }
                if(isvalid(vecin) && dist[vecin.lin][vecin.col] < mid && a[vecin.lin][vecin.col] != 'D' && a[vecin.lin][vecin.col] != '*'){
                    ok = false;
                    break;
                }
                if(a[vecin.lin][vecin.col] == 'O'){
                    amajuns = true;
                    break;
                }
            }
        }
        while(!Q.empty()){
            Q.pop();
        }
        if(ok == true){
            sol = mid;
            left = mid + 1;
        } else{
            right = mid - 1;
        }
    }
    g << sol ;
}