Cod sursa(job #2543790)

Utilizator iulianarsenoiuArsenoiu Iulian iulianarsenoiu Data 11 februarie 2020 15:29:31
Problema Barbar Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.06 kb
#include <fstream>
#include <queue>

using namespace std;
ifstream f("barbar.in");
ofstream g("barbar.out");
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int n,m,a[1005][1005],b[1005][1005],d[1005][1005],xi,yi,xf,yf;
queue <pair<int,int>> q;
void bordare(int n, int m)
{
    for(int i=0;i<=n+1;i++)
    {
        a[i][0]=a[i][m+1]=b[i][0]=b[i][m+1]=d[i][0]=d[i][m+1]=-1;
    }
    for(int i=0;i<=m+1;i++)
    {
        a[0][i]=a[n+1][i]=b[0][i]=b[n+1][i]=d[0][i]=d[n+1][i]=-1;
    }
}
void reset()
{
    for(int i=0;i<=n+1;i++)
    {
        for(int j=0;j<=m+1;j++)
        {
            a[i][j]=b[i][j];
        }
    }
}
void Fill(int i, int j, int dst)
{
    a[i][j]=-1;
    for(int p=0;p<4;p++)
    {
        int xx=i+dx[p];
        int yy=j+dy[p];
        if(!a[xx][yy] && d[xx][yy]-1>=dst)
        {
            Fill(xx,yy,dst);
        }
    }
}
void Lee()
{
    while(!q.empty())
    {
        int x=q.front().first;
        int y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++)
        {
            int xx=x+dx[i];
            int yy=y+dy[i];
            if(!d[xx][yy])
            {
                q.push({xx,yy});
                d[xx][yy]=d[x][y]+1;
            }
        }
    }
    /// acum stim pentru fiecare celula cat de apropiat e cel mai apropiat dragon
}
int main()
{
    ///personajul principal o sa fie Jonel pentru ca suna mai bine decat Paftenie
    f>>n>>m;
    bordare(n,m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char ch;
            f>>ch;
            if(ch=='I') ///de aici pleaca Jonel
            {
                xi=i;
                yi=j;
            }
            else if(ch=='O') ///aici ajunge Jonel
            {
                xf=i;
                yf=j;
            }
            else if(ch=='*') ///pe aici nu poate trece Jonel
            {
                a[i][j]=-1;
                b[i][j]=-1; ///"b" va ramane mereu matricea initiala, o vom folosi pentru a reseta matricea "a" dupa ce aceasta din urma va fi stricata
                d[i][j]=-1;
            }
            else if(ch=='D') ///de asta fuge Jonel
            {
                q.push({i,j}); ///punem in coada ca de fiecare data sa stim cat de aproape de Jonel e un dragon
                d[i][j]=1;
            }
        }
    }
    Lee(); ///calculam distantele fata de Jonel
    ///cautam binar distanta, folosind algoritmul de Fill pentru a afla daca distanta e prea mare sau nu
    /// daca e prea mare, adica Jonel nu va ajunge la iesire pastrand distanta, vom continua cautarea in intervalul st,mij-1, altfel in intervalul mij+1,dr
    int st=1,dr=d[xi][yi];
    int rez=0;
    bool ok=false;
    while(st<=dr)
    {
        int mij=(st+dr)/2;
        reset();
        Fill(xi,yi,mij);
        if(a[xf][yf]==0)
        {
            dr=mij-1;
        }
        else
        {
            ok=true;
            rez=mij;
            st=mij+1;
        }
    }
    if(ok)
    g<<rez<<'\n';
    else g<<-1<<'\n';
    return 0;
}