Cod sursa(job #3150106)

Utilizator PescarusTanislav Luca Andrei Pescarus Data 14 septembrie 2023 21:00:12
Problema Barbar Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <fstream>
#include <queue>
#include <climits>
using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
const int nmax = 1005;
struct cell {
    int lin, col;
};
int r, c;
int dist[nmax][nmax], a[nmax][nmax];
int viz[nmax][nmax];
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

bool verificare(int a, int b){
    return (a >= 1 && a <= r && b >= 1 && b <= c);
}
int main(){
    queue<cell> q;
    f >> r >> c;
    int start1, start2;
    int final1, final2;
    for(int i = 1; i <= r; i++){
        for(int j = 1; j <= c; j++){
            char c;
            f >> c;
            dist[i][j] = -5;
            if(c == '.'){
                a[i][j] = 0;
            }
            if(c == 'I'){
                a[i][j] = 0;
                start1 = i;
                start2 = j;
            }
            if(c == 'D'){
                a[i][j] = 0;
                dist[i][j] = 0;
                q.push({i, j});
            }
            if(c == '*'){
                a[i][j] = -1;
                dist[i][j] = -1;
            }
            if(c == 'O'){
                a[i][j] = 0;
                final1 = i;
                final2 = j;
            }
        }
    }
    while(!q.empty()){
        cell celula = q.front();
        q.pop();
        for(int dir = 0; dir < 4; dir++){
            int lnou = celula.lin + dx[dir];
            int cnou = celula.col + dy[dir];
            if(verificare(lnou, cnou) && a[lnou][cnou] != -1 && dist[lnou][cnou] == -5){
                q.push({lnou, cnou});
                dist[lnou][cnou] = dist[celula.lin][celula.col] + 1;
            }
        }
    }
  /* for(int i = 1; i <= r; i++){
        for(int j = 1; j <= c; j++){
            cout << dist[i][j] << ' ';
        }
        cout << '\n';}*/
    
   // cout << final1 << ' ' << final2;
    int st = 1, dr = r + c;
    int sol = 0;
    while(st <= dr){
        int mid = (st + dr) / 2;
        if(dist[start1][start2] < mid){
            dr = mid - 1;
            continue;
        }
        queue<cell> qu;
        qu.push({start1, start2});
        viz[start1][start2] = 1;
        bool ok = 0;
        while(!qu.empty()){
            cell celula = qu.front();
            qu.pop();
            viz[celula.lin][celula.col] = 1;
            for(int dir = 0; dir < 4; dir++){
                int lnou = celula.lin + dx[dir];
                int cnou = celula.col + dy[dir];
                if(verificare(lnou, cnou) && dist[lnou][cnou] >= mid && viz[lnou][cnou] == 0){
                       qu.push({lnou, cnou});
                       if(lnou == final1 && cnou == final2){
                            ok = 1;
                            break;
                       } 
                }
            }
            if(ok == 1){
                break;
            }
        }
        if(ok == 1){
            st = mid + 1;
            sol = mid;
        }
        else{
            dr = mid - 1;
        }
        for(int i = 1; i <= r; i++){
            for(int j = 1; j <= c; j++){
                viz[i][j] = 0;
            }
        }
    }
    g << sol << '\n'; 
    
}