Cod sursa(job #2326886)

Utilizator marcogoldPop Mihali Marco Silviu marcogold Data 24 ianuarie 2019 10:39:32
Problema Barbar Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.67 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];
int Citit[1005][1005];
int 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],estesol=false;
point start,dragoni[10000],finish;
queue<point> coada;


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;
}

bool LeeCalc(int minim)
{
    resetare();
    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();

        for(int i=0; i<=3; i++)
        {
            int nextX=X+dirI[i];
            int nextY=Y+dirJ[i];

            if(inside(nextX,nextY) && Citit[nextX][nextY]!=-1 && viz[nextX][nextY]==false && DistMinDragon[nextX][nextY]>=minim)
            {
                if(nextX==finish.x && nextY==finish.y)
                {

                    while(coada.empty()==false)
                        coada.pop();

                    return true;
                }
                point urmator;
                urmator.x=nextX;
                urmator.y=nextY;
                viz[nextX][nextY]=true;
                coada.push(urmator);


            }
        }

    }

    return 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;
                point inceput;
                inceput.x=i;
                inceput.y=j;
                coada.push(inceput);
                Citit[i][j]=3;
                DistMinDragon[i][j]=0;
                viz[i][j]=true;
            }
            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;
            }
        }


    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 && inside(nextX,nextY) && viz[nextX][nextY]==false) ///nu este obstacol
            {
                coada.push(vecin);
                DistMinDragon[nextX][nextY]= DistMinDragon[X][Y]+1;
                viz[nextX][nextY]=true;
            }

        }
    }



int poz=0;

for(int k=19; k>=0; k--)
{
    if(poz+(1<<k) <=1000 && LeeCalc(poz+(1<<k))==true )
    {
        estesol=true;
        poz+=(1<<k);
    }
}

if(estesol==true)
    fo<<poz;
else
    fo<<-1;



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