Cod sursa(job #3150084)

Utilizator PescarusTanislav Luca Andrei Pescarus Data 14 septembrie 2023 18:49:19
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.84 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];
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] = 1;
                start1 = i;
                start2 = j;
            }
            if(c == 'D'){
                a[i][j] = -2;
                dist[i][j] = 0;
            }
            if(c == '*'){
                a[j][i] = -1;
                dist[i][j] = -1;
            }
            if(c == 'O'){
                a[i][j] = 2;
                final1 = i;
                final2 = j;
            }
        }
    }
    for(int i = 1; i <= r; i++){
        for(int j = 1; j <= c; j++){
            if(a[i][j] == -2){
                q.push({i, 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;
            }
        }
    }
    int st = 1, dr = r + c;
    int sol = 0;
    while(st <= dr){
        int mid = (st + dr) / 2;
        queue<cell> qu;
        qu.push({start1, start2});
        bool ok = 0;
        while(!q.empty()){
            cell celula = q.front();
            q.pop();
            if(celula.lin == start1 && celula.col == start2){
                continue;
            }
            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){
                       q.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;
        }
    }
    g << sol << '\n';

}