Cod sursa(job #2325933)

Utilizator marcogoldPop Mihali Marco Silviu marcogold Data 23 ianuarie 2019 11:08:26
Problema Barbar Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.76 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];
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;
                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;
                }

            }
        }
    }

    int sol=-1;

 int poz=0;

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

  if(poz==0)
    fo<<-1;
  else
    fo<<poz;
    fo.close();
    fi.close();
    return 0;
}