Cod sursa(job #2325772)

Utilizator marcogoldPop Mihali Marco Silviu marcogold Data 22 ianuarie 2019 21:54:52
Problema Barbar Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.95 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

struct point
{
    int x,y;
};
int DistMinDragon[1005][1005],Citit[1005][1005],Lee[1005][1005];
int n,m,nrdrag,dirI[4]= {0,0,-1,1},dirJ[4]= {1,-1,0,0};
char x;
bool viz[1005][1005];
point start,dragoni[10000],finish;
queue<point> coada;

void afisare()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
            fo<<Lee[i][j]<<"            ";
        fo<<endl;
    }
}

bool inside(int a,int b)
{
    if( a<1 || a>n || b<1 || b>m)
        return false;

    return true;
}
void resetare()
{
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            viz[i][j]=false;
}

///3 dragon
/// 0 liber
/// -1 obstacol
/// 1 start
/// 4 finish
int main()
{
    fi>>n>>m;

    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            Lee[i][j]=200000;

    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            DistMinDragon[i][j]=200000;

    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
        {
            fi>>x;
            if(x=='I')
            {
                start.x=i;
                start.y=j;
                Citit[i][j]=1;
            }
            if(x=='D')
            {
                nrdrag++;
                dragoni[nrdrag].x=i;
                dragoni[nrdrag].y=j;
                Citit[i][j]=3;
            }
            if(x=='.')
                Citit[i][j]=0;
            if(x=='*')
                Citit[i][j]=-1;
            if(x=='O')
            {
                Citit[i][j]=4;
                finish.x=i;
                finish.y=j;
            }

        }

    for(int i=1; i<=nrdrag; i++)
    {
        resetare();
        point inceput;
        inceput.x=dragoni[i].x;
        inceput.y=dragoni[i].y;
        DistMinDragon[inceput.x][inceput.y]=0;

        coada.push(inceput);


        while(coada.empty()==false)
        {

            int  X=coada.front().x;
            int Y=coada.front().y;
            coada.pop();

            for(int directie=0; directie<=3; directie++)
            {
                int nextX=X+dirI[directie];
                int nextY=Y+dirJ[directie];
                point vecin;
                vecin.x=nextX;
                vecin.y=nextY;

                if(Citit[nextX][nextY]!=-1 && DistMinDragon[X][Y]+1<DistMinDragon[nextX][nextY] && inside(nextX,nextY)) ///nu este obstacol
                {
                    coada.push(vecin);
                    DistMinDragon[nextX][nextY]= DistMinDragon[X][Y]+1;
                }


            }
        }

    }


///start

    coada.push(start);
    viz[start.x][start.y]=true;

    while(coada.empty()==false)
    {

        int X=coada.front().x;
        int Y=coada.front().y;
        coada.pop();


        Lee[X][Y]=min(DistMinDragon[X][Y],Lee[X][Y]);
        for(int i=0; i<=3; i++)
        {
            int nextX=X+dirI[i];
            int nextY=Y+dirJ[i];
            point urmator;
            urmator.x=nextX;
            urmator.y=nextY;

            if( Citit[X][Y]!=-1 && inside(nextX,nextY))
            {

                if(viz[nextX][nextY]==false)
                {

                    Lee[nextX][nextY]=min(Lee[X][Y],DistMinDragon[nextX][nextY]);
                    coada.push(urmator);
                    viz[nextX][nextY]=true;
                }
                else if( min(Lee[X][Y],DistMinDragon[nextX][nextY])>Lee[nextX][nextY] )
                {
                    Lee[nextX][nextY]=min(Lee[X][Y],DistMinDragon[nextX][nextY]);
                    coada.push(urmator);
                }

            }


        }
    }

     if(Lee[finish.x][finish.y]==100000 )
         cout<<-1;
     else
         cout<<Lee[finish.x][finish.y];


    afisare();

    fo.close();
    fi.close();
    return 0;
}