Cod sursa(job #1840839)

Utilizator GoogalAbabei Daniel Googal Data 4 ianuarie 2017 21:39:34
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.03 kb
#include <fstream>
#include <cstring>
#include <queue>
#define nmax 1001

using namespace std;

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

int r,c,a[nmax][nmax],startx,starty,stopx,stopy,maxx;
bool d[nmax][nmax];
char x;

int dx[]= {-1, 1, 0, 0};
int dy[]= { 0, 0,-1, 1};

queue < pair < int, int > > coada;

inline void read()
{
    fin>>r>>c;
    noskipws(fin);
    fin>>x;
    for(int i=1; i<=r; i++)
    {
        for(int j=1; j<=c; j++)
        {
            fin>>x;
            if(x=='I')
            {
                startx=i;
                starty=j;
            }
            else if(x=='D')
            {
                coada.push(make_pair(i,j));
                a[i][j]=1;
            }
            else if(x=='*')
            {
                a[i][j]=-1;
            }
            else if(x=='O')
            {
                stopx=i;
                stopy=j;
            }
        }
        fin>>x;
    }
    fin.close();
}

bool ok(int x, int y)
{
    if(x<1 || y<1 || x>r || y>c || a[x][y]==-1)
        return false;
    return true;
}

inline void dragons()
{
    int x,y;
    while(!coada.empty())
    {
        x=coada.front().first;
        y=coada.front().second;
        coada.pop();
        for(int directie=0; directie<4; directie++)
        {
            if(ok(x+dx[directie],y+dy[directie]))
            {
                int x_urm=x+dx[directie];
                int y_urm=y+dy[directie];
                if(!a[x_urm][y_urm] || a[x][y]+1<a[x_urm][y_urm])
                {
                    a[x_urm][y_urm]=a[x][y]+1;
                    if(a[x][y]+1>maxx)
                        maxx=a[x][y]+1;
                    coada.push(make_pair(x_urm,y_urm));
                }
            }
        }
    }
}

bool valid(int k)
{
    int x,y;
    if(a[startx][starty]<k || a[stopx][stopy]<k)
        return false;
    while(!coada.empty())
        coada.pop();
    coada.push(make_pair(startx,starty));
    while(!coada.empty())
    {
        x=coada.front().first;
        y=coada.front().second;
        d[x][y]=-1;
        if(x==stopx && y==stopy)
            return true;
        coada.pop();
        for(int directie=0; directie<4; directie++)
        {
            int x_urm=x+dx[directie];
            int y_urm=y+dy[directie];
            if(ok(x_urm,y_urm) && d[x_urm][y_urm]==false)
            {
                if(a[x_urm][y_urm]>=k)
                {
                    coada.push(make_pair(x_urm,y_urm));
                    d[x_urm][y_urm]=true;
                }
            }
        }
    }
    return false;
}

int caut()
{
    int pas=1<<17,r=0;
    while(pas!=0)
    {
        if(r+pas<=maxx && valid(r+pas))
            r+=pas;
        memset(d,false,sizeof(d));
        pas/=2;
    }
    if(!r)
        return -1;
    return r;
}

int main()
{
    int zz;
    read();
    dragons();
    zz=caut();
    if(zz<0)
        fout<<-1;
    else
        fout<<zz-1;
    fout.close();
    return 0;
}