Cod sursa(job #1657300)

Utilizator llalexandruLungu Alexandru Ioan llalexandru Data 20 martie 2016 13:02:48
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.64 kb
#include <fstream>
#define NM 4000005

using namespace std;

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

struct cf{int x, y;};

int x, y, xs, ys, xf, yf, M[2005][2005], maxcf, last, sol=-1, maxim;
char c;

cf Coada[NM], D[NM];
int Valid[2005][2005];

int Test(int lim)
{
    int st, fi, actx, acty, i, j;
    for (i=1; i<=x; i++)
        for (j=1; j<=y; j++)
            Valid[i][j]=0;
    st=1;
    fi=1;
    Coada[1].x=xs;
    Coada[1].y=ys;
    Valid[xs][ys]=1;
    while (st<=fi)
    {
        actx=Coada[st].x;
        acty=Coada[st].y;
        st++;
        if (actx==xf && acty==yf)
            return 1;
        if (M[actx-1][acty]>=lim && Valid[actx-1][acty]==0)
        {
            Valid[actx-1][acty]=1;
            fi++;
            Coada[fi].x=actx-1;
            Coada[fi].y=acty;
        }
        if (M[actx+1][acty]>=lim && Valid[actx+1][acty]==0)
        {
            Valid[actx+1][acty]=1;
            fi++;
            Coada[fi].x=actx+1;
            Coada[fi].y=acty;
        }
        if (M[actx][acty-1]>=lim && Valid[actx][acty-1]==0)
        {
            Valid[actx][acty-1]=1;
            fi++;
            Coada[fi].x=actx;
            Coada[fi].y=acty-1;
        }
        if (M[actx][acty+1]>=lim && Valid[actx][acty+1]==0)
        {
            Valid[actx][acty+1]=1;
            fi++;
            Coada[fi].x=actx;
            Coada[fi].y=acty+1;
        }
    }
    return 0;
}

void Cautare()
{
    int l=1, r=maxim, mijl, ok;
    if (Test(0))
        sol=0;
    while (l<=r)
    {
        mijl=(l+r)/2;
        ok=Test(mijl);
        if (ok && M[xs][ys]>=mijl)
        {
            sol=mijl;
            l=mijl+1;
        }
        else
        {
            r=mijl-1;
        }
    }
    fout<<sol;
}

void Bordare()
{
    int i;
    for (i=0; i<=x+1; i++)
    {
        M[i][0]=M[i][y+1]=-1;
    }
    for (i=0; i<=y+1; i++)
    {
        M[0][i]=M[x+1][i]=-1;
    }
}

void Build()
{
    int st, fi;
    cf act;
    st=1;
    fi=maxcf;
    while (st<=fi)
    {
        act=Coada[st];
        st++;
        if (M[act.x-1][act.y]==0)
        {
            Coada[++fi].x=act.x-1;
            Coada[fi].y=act.y;
            M[act.x-1][act.y]=M[act.x][act.y]+1;
        }
        if (M[act.x+1][act.y]==0)
        {
            Coada[++fi].x=act.x+1;
            Coada[fi].y=act.y;
            M[act.x+1][act.y]=M[act.x][act.y]+1;
        }
        if (M[act.x][act.y-1]==0)
        {
            Coada[++fi].x=act.x;
            Coada[fi].y=act.y-1;
            M[act.x][act.y-1]=M[act.x][act.y]+1;
        }
        if (M[act.x][act.y+1]==0)
        {
            Coada[++fi].x=act.x;
            Coada[fi].y=act.y+1;
            M[act.x][act.y+1]=M[act.x][act.y]+1;
        }
    }
}

int main()
{
    int i, j;
    fin>>x>>y;
    for (i=1; i<=x; i++)
    {
        for (j=1; j<=y; j++)
        {
            fin>>c;
            if (c=='I')
            {
                xs=i;
                ys=j;
            }
            if (c=='D')
            {
                Coada[++maxcf].x=i;
                Coada[maxcf].y=j;
                D[++last].x=i;
                D[last].y=j;
            }
            if (c=='*')
                M[i][j]=-1;
            if (c=='O')
            {
                xf=i;
                yf=j;
            }
        }
    }
    Bordare();
    Build();
    for (i=1; i<=x; i++)
        for (j=1; j<=y; j++)
            if (M[i][j]>maxim)
                maxim=M[i][j];
    for (i=1; i<=last; i++)
        M[D[i].x][D[i].y]=0;
    Cautare();
    return 0;
}