Cod sursa(job #2516657)

Utilizator Rares31100Popa Rares Rares31100 Data 1 ianuarie 2020 21:30:17
Problema Barbar Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <bits/stdc++.h>
#define Mod 1000000
#define Lin first
#define Col second

using namespace std;

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

int n,m;
string temn[1000];

int dLin[]={-1,0,1,0},dCol[]={0,1,0,-1};
int dist[1001][1001];
short int viz[1001][1001];

pair <int,int> cDrag[1000000];
int lastDr=1,vfDr;

pair <int,int> cErou[1000000];
int drum[1001][1001];
int lastE=1,vfE;

bool inUse[1001][1001];
int iSt,jSt,iEnd,jEnd;

int main()
{
    in>>n>>m;

    for(int i=0;i<n;i++)
        in>>temn[i];

    for(int i=0;i<=n+1;i++)
        viz[i][0]=viz[i][m+1]=1;

    for(int j=0;j<=m+1;j++)
        viz[0][j]=viz[n+1][j]=1;

    for(int i=0;i<=n-1;i++)
        for(int j=0;j<=m-1;j++)
            switch(temn[i][j])
            {
                case '.':
                    break;
                case '*':
                    viz[i+1][j+1]=1;
                    break;
                case 'D':
                    viz[i+1][j+1]=1;
                    cDrag[++vfDr]={i+1,j+1};
                    break;
                case 'I':
                    iSt=i+1;jSt=j+1;
                    break;
                case 'O':
                    iEnd=i+1;jEnd=j+1;
                    break;
                default:break;
            }

    while(lastDr<=vfDr)
    {
        int i=cDrag[lastDr%Mod].Lin;
        int j=cDrag[lastDr%Mod].Col;
        lastDr++;

        inUse[i][j]=0;

        int id,jd;
        for(int k=0;k<=3;k++)
        {
            id=i+dLin[k];
            jd=j+dCol[k];

            if(!viz[id][jd])
            {
                dist[id][jd]=dist[i][j]+1;
                viz[id][jd]=2;

                inUse[id][jd]=1;
                cDrag[++vfDr%Mod]={id,jd};
            }
            else if(viz[id][jd]==2 && dist[id][jd]>dist[i][j]+1)
            {
                dist[id][jd]=dist[i][j]+1;

                if(inUse[id][jd]==0)
                {
                    inUse[id][jd]=1;
                    cDrag[++vfDr%Mod]={id,jd};
                }
            }
        }
    }

    cErou[++vfE]={iSt,jSt};
    viz[iSt][jSt]=3;
    drum[iSt][jSt]=dist[iSt][jSt];

    while(lastE<=vfE)
    {
        int i=cErou[lastE%Mod].Lin;
        int j=cErou[lastE%Mod].Col;
        lastE++;

        int id,jd;
        for(int k=0;k<=3;k++)
        {
            id=i+dLin[k];
            jd=j+dCol[k];

            if(viz[id][jd]==2)
            {
                drum[id][jd]=min(drum[i][j],dist[id][jd]);
                viz[id][jd]=3;

                inUse[id][jd]=1;
                cErou[++vfE%Mod]={id,jd};
            }
            else if(viz[id][jd]==3 && min(drum[i][j],dist[id][jd])>drum[id][jd])
            {
                drum[id][jd]=min(drum[i][j],dist[id][jd]);

                if(inUse[id][jd]==0)
                {
                    inUse[id][jd]=1;
                    cErou[++vfE%Mod]={id,jd};
                }
            }
        }
    }

    if(viz[iEnd][jEnd]==2)
        out<<-1;
    else
        out<<drum[iEnd][jEnd];

    return 0;
}