Cod sursa(job #3299273)

Utilizator InformaticianInDevenire1Munteanu Mihnea Gabriel InformaticianInDevenire1 Data 5 iunie 2025 10:44:47
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.8 kb
#include <bits/stdc++.h>
#define fi first
#define se second

using namespace std;

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

const int CNST = 1e4;
int n,m;
char ch[1005][1005];
int viz[1005][1005];
int Lee[1005][1005];
int dx[4],dy[4];
queue <pair <int,int>> q;
struct Node{
    int val;
    int I;
    int J;
} heap[200005];

void MakeDs(){
    dx[1] = 0;
    dx[3] = 0;
    dx[0] = -1;
    dx[2] = 1;
    dy[0] = 0;
    dy[2] = 0;
    dy[1] = 1;
    dy[3] = -1;
    return;
}

bool IsInMatrix(int i,int j){
    if (i<1 or n<i) return 0;
    if (j<1 or m<j) return 0;
    return 1;
}

bool IsWalkable(int i,int j){
    if (ch[i][j]=='I' or ch[i][j]=='O' or ch[i][j]=='.') return 1;
    return 0;
}

void Lee_Function(){
    while (!q.empty()){
        int x = q.front().first, y = q.front().second;
        q.pop();
        for (int k=0;k<=3;++k){
            int nx = x+dx[k], ny = y+dy[k];
            if (IsInMatrix(nx,ny)==1 and Lee[nx][ny]==CNST){
                Lee[nx][ny] = Lee[x][y]+1;
                q.push({nx,ny});
            }
        }
    }
    return;
}

int father(int x){
    return x/2;
}

int leftSon (int x){
    return 2*x;
}

int rightSon (int x) {
    return 2*x+1;
}

void swapNodes (int n1, int n2) {
    swap(heap[n1],heap[n2]);
}

void topComparison (int nodePos) {
    while (nodePos>1 and heap[nodePos].val>heap[father(nodePos)].val) {
        swapNodes(nodePos,father(nodePos));
        nodePos = father(nodePos);
    }
    return;
}


void bottomComparison (int nodePos, int &heapsize){
    int son = -1;
    if (leftSon(nodePos)<=heapsize){
        son = leftSon(nodePos);
        if (rightSon(nodePos)<=heapsize and heap[rightSon(nodePos)].val>heap[leftSon(nodePos)].val) {
            son = rightSon(nodePos);
        }
    }
    if (son==-1) return;
    if (heap[son].val>heap[nodePos].val) {
        swapNodes(son,nodePos);
        bottomComparison(son,heapsize);
    }
}

void Insert(int xValue, int II,int JJ, int &heapsize) {
    heapsize++;
    heap[heapsize].val = xValue;
    heap[heapsize].I = II;
    heap[heapsize].J = JJ;
    topComparison(heapsize);
}

void Delete(int index, int &heapsize){
    swapNodes(index, heapsize);
    heapsize--;
    topComparison(index);
    bottomComparison(index, heapsize);
}

signed main()
{
    ios::sync_with_stdio(false);
    fin.tie(NULL);
    fout.tie(NULL);
    MakeDs();
    fin >> n >> m;
    int ist = 0,jst = 0;
    int ifn = 0,jfn = 0;
    for (int i=1;i<=n;++i){
        for (int j=1;j<=m;++j){
            fin >> ch[i][j];
            Lee[i][j] = CNST;
            if (!IsWalkable(i,j)) Lee[i][j] += CNST;
            if (ch[i][j]=='I'){
                ist = i;
                jst = j;
            }
            if (ch[i][j]=='O'){
                ifn = i;
                jfn = j;
            }
        }
    }
    for (int i=1;i<=n;++i){
        for (int j=1;j<=m;++j){
            if (ch[i][j]=='D'){
                q.push({i,j});
                Lee[i][j] = 0;
            }
        }
    }
    Lee_Function();
    int heapsize = 0;
    Insert(Lee[ist][jst],ist,jst,heapsize);
    viz[ist][jst] = 1;
    int ans = Lee[ist][jst];
    bool loob = 0;
    while (heapsize){
        int x = heap[1].I, y = heap[1].J;
        ans = ans>Lee[x][y] ? Lee[x][y] : ans;
        if (x==ifn and y==jfn){
            loob = 1;
            break;
        }
        Delete(1,heapsize);
        for (int k=0;k<=3;++k){
            int nx = x+dx[k], ny = y+dy[k];
            if (IsInMatrix(nx,ny) and IsWalkable(nx,ny)==1 and viz[nx][ny]==0){
                Insert(Lee[nx][ny],nx,ny,heapsize);
                viz[nx][ny] = 1;
            }
        }
    }
    if (loob==0) ans = -1;
    fout << ans;
    return 0;
}