Cod sursa(job #2100976)

Utilizator GiihuoTihufiNeacsu Stefan GiihuoTihufi Data 6 ianuarie 2018 17:37:36
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.38 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

#define FREE      1002
#define WALL     -   1
#define DRAGON       0
#define O         1003
#define I         1004

vector<int> DX,DY;

int M[1002][1002]={0};
int m,n;
int OX,OY,IX,IY;

void Read()
{
    f>>m>>n;

    char c;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            f>>c;
            switch(c)
            {
                case '.':M[i][j]=FREE;   break;
                case '*':M[i][j]=WALL;   break;
                case 'D':M[i][j]=DRAGON; DX.push_back(i); DY.push_back(j);
                                         break;
                case 'O':M[i][j]=O;      OX=i,OY=j;
                                         break;
                case 'I':M[i][j]=I;      IX=i,IY=j;
                                         break;
            }
        }
    }
}

int distmin=0;

bool Check(int i,int x,int y,vector<int> &vX,vector<int> &vY)
{
    int _i=DX[i]+x, _j=DY[i]+y;
    if (M[_i][_j]==FREE || M[_i][_j]==I || M[_i][_j]==O)
    {
        vX.push_back(_i), vY.push_back(_j);
        if(M[_i][_j]==FREE) M[_i][_j]=distmin;
    }
    return M[_i][_j]==O || M[_i][_j]==I;
}


bool ExpandDragon()  ///Parcurgerea acopera O sau I? (Check)
{
    bool result=0;
    distmin++;
    vector<int> dX,dY;

    int N=DX.size();
    for(int i=0;i<N;i++)
    {
        result|=Check(i,-1, 0,dX,dY) || Check(i, 1, 0,dX,dY) ||
                Check(i, 0,-1,dX,dY) || Check(i, 0, 1,dX,dY);
    }
    DX=dX;
    DY=dY;
    return result;
}

vector<int> X(1,OX), Y(1,OY);

int D[1002][1002];

bool CheckS(int i,int x,int y,vector<int> &vX,vector<int> &vY)
{
    int _i=X[i]+x, _j=Y[i]+y;
    if (D[_i][_j]==FREE || M[_i][_j]==I)
        vX.push_back(_i), vY.push_back(_j), D[_i][_j]=1;
    return (_i==IX && _j==IY);
}

bool Simulate()  ///E disponibil drumul O-I ?
{
    X.clear(); X.push_back(OX);
    Y.clear(); Y.push_back(OY);
    bool result=0;

    do
    {
        vector<int> sX(0,0),sY(0,0);
        int N=X.size();
        for(int i=0;i<N;i++)
        {
            result |= CheckS(i,-1, 0,sX,sY) || CheckS(i, 1, 0,sX,sY) ||
                      CheckS(i, 0,-1,sX,sY) || CheckS(i, 0, 1,sX,sY) ;
        }
        /*for(int i=0;i<N;i++) cout<<X[i]<<" ";
        cout<<endl;
        for(int i=0;i<N;i++) cout<<Y[i]<<" ";
        cout<<endl<<result;
        getchar();*/
        X=sX, Y=sY;
    }   while(!result && X.size()!=0);
    return result;
}

void Write()
{
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
    {
        switch(M[i][j])
        {
            case FREE: cout<<"."; break;
            case WALL: cout<<"*"; break;
            case DRAGON: cout<<"D"; break;
            case I: cout<<"I"; break;
            case O: cout<<"O"; break;
            default:cout<<M[i][j];
        }
    }
        cout<<endl;
    }
    cout<<endl;
}

int main()
{
    Read();
    bool b=1,c=0,c1;

    copy(M,M+1002,D);
    if(Simulate())
    {
        while(b && !c)
        {
            c1=c;
            c|=ExpandDragon();
            copy(M,M+1002,D);
            //Write();
            b=Simulate();
            //cout<<b<<c<<endl;
        }
    }else distmin=0;
    if(c1) g<<-1;
    else g<<distmin;
    return 0;
}