Cod sursa(job #2503311)

Utilizator cyg_Alex_codegicianBarbu Alexandru cyg_Alex_codegician Data 2 decembrie 2019 20:43:15
Problema Barbar Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("barbar.in");
ofstream fout("barbar.out");
int mat[1005][1005],lee[1005][1005],rez[1005][1005];
int r,c,nrDrag,poz;
int dx[4]={0,0,1,-1},dy[4]={-1,1,0,0};
pair <int,int> drag[1000005],start,final;
queue <pair<int,int>> q;
void bordare(int a[][1005])
{
    for (int i=0;i<=r+1;i++)
    {
        a[i][0]=a[i][c+1]=-1;
    }
    for (int j=0;j<=c+1;j++)
    {
        a[0][j]=a[r+1][j]=-1;
    }
}
void algLee()
{
    while (!q.empty())
    {
        int okx=q.front().first;
        int oky=q.front().second;
        q.pop();
        for (int i=0;i<4;i++)
        {
            int x2=okx+dx[i];
            int y2=oky+dy[i];
            if ((lee[x2][y2]>lee[okx][oky]+1 || lee[x2][y2]==0) && mat[x2][y2]!=-1)
            {
                lee[x2][y2]=lee[okx][oky]+1;
                q.push(make_pair(x2,y2));
            }
        }
    }
}
int drum(int mij)
{
    for (int i=1;i<=r;i++)
    {
        for (int j=1;j<=c;j++)
        {
            rez[i][j] = 0;
        }
    }
    while (!q.empty())
    {
        q.pop();
    }
    rez[start.first][start.second]=1;
    if (lee[start.first][start.second]>=mij) q.push(start);
    while (!q.empty())
    {
        int okx=q.front().first;
        int oky=q.front().second;
        q.pop();
        if (okx==final.first && oky==final.second) return 1;
        for (int i=0;i<4;i++)
        {
            int x2=okx+dx[i];
            int y2=oky+dy[i];
            if ((lee[x2][y2]>=mij) && (rez[x2][y2]>rez[okx][oky]+1 || rez[x2][y2]==0))
            {
                rez[x2][y2]=rez[okx][oky]+1;
                q.push(make_pair(x2,y2));
            }
        }
    }
    return 0;
}
void cautBin(int st, int dr)
{
    while (st <= dr)
    {
        int mij=(st + dr)/2;
        if (drum(mij)==1)
        {
            poz=mij;
            st=mij+1;
        }
        else dr=mij-1;
    }
}
int main()
{
    fin >> r >> c;
    bordare(lee);
    bordare(rez);
    for (int i = 1; i <= r; i++)
        for (int j = 1; j <= c; j++)
        {
            char x;
            fin >> x;
            if (x=='.') mat[i][j]=0;
            else if (x=='*') mat[i][j]=-1;
            else if (x=='D')
            {
                mat[i][j]=-1;
                drag[++nrDrag]=make_pair(i,j);
            }
            else if (x=='I')
            {
                mat[i][j]=0;
                start=make_pair(i,j);
            }
            else if (x=='O')
            {
                mat[i][j]=0;
                final=make_pair(i, j);
            }
        }
    
    for (int i=1;i<=nrDrag;i++)
    {
        q.push(make_pair(drag[i].first,drag[i].second));
    }
    algLee();
    cautBin(0,r*c);
    if (poz == 0) poz = -1;
    fout << poz << "\n";
}