Cod sursa(job #602260)

Utilizator acelasi7Tudor Maxim acelasi7 Data 10 iulie 2011 12:21:15
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.7 kb
#include<cstdio>
#include<fstream>
#include<queue>
#include<iomanip>
#include<climits>
using namespace std;

#define nrn 1024
#define inf INT_MAX
struct punct{int x,y;}s,f,p;
queue<punct>Q;
const int dx[]={0,0,0,-1,1};
const int dy[]={0,-1,1,0,0};
int a[nrn][nrn],m[nrn][nrn],ok,sol,L,C;

void citire()
{
    int i,j;
    char x;
    //FILE *in=fopen("barbar.in","r");
    ifstream in("barbar.in");
    //fscanf(in,"%d %d\n",&L,&C);
    in>>L>>C;
    sol=-1;
    in.get();
    for(i=1;i<=L;++i)
    {
        for(j=1;j<=C;++j)
        {
            //fscanf(in,"%c",&x);
            in.get(x);
            switch(x)
            {
                case('*'):
                a[i][j]=-1;
                m[i][j]=-1;
                break;

                case('D'):
                //a[i][j]=-2;
                m[i][j]=-2;
                p.x=i;
                p.y=j;
                Q.push(p);
                break;

                case('I'):
                s.x=i;
                s.y=j;
                break;

                case('O'):
                f.x=i;
                f.y=j;
                break;
            }
        }
        //fscanf(in,"\n");
        in.get();
    }
    //fclose(in);
    for(i=0;i<=L+1;++i)
        a[i][0]=a[i][C+1]=m[i][0]=m[i][C+1]=-1;
    for(j=1;j<=C;++j)
        a[0][j]=a[L+1][j]=m[0][j]=m[L+1][j]=-1;
}

int bfs(int val)
{
    int x,y,i,xx,yy;
    Q.push(s);
    while(!Q.empty())
    {
        p=Q.front();
        Q.pop();
        x=p.x;
        y=p.y;
        for(i=1;i<5;++i)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if(m[xx][yy]!=-1)
            {
                if(m[xx][yy]==-2)
                {
                    m[xx][yy]=0;
                    a[xx][yy]=-2;
                }
                if(m[xx][yy]==inf || (m[xx][yy]<m[x][y] && m[xx][yy]<a[xx][yy]))
                {
                    if(a[xx][yy]==-2)
                        m[xx][yy]=0;
                    else
                        m[xx][yy]=min(m[x][y],a[xx][yy]);


                    if(m[xx][yy]>=val)
                    {
                        if(xx==f.x && yy==f.y)
                        {
                            while(!Q.empty())
                                Q.pop();
                            return 1;
                        }
                        p.x=xx;
                        p.y=yy;
                        Q.push(p);
                    }
                }
            }
        }
    }
    return 0;
}

void curat()
{
    int i,j;
    for(i=1;i<=L;++i)
        for(j=1;j<=C;++j)
            if(m[i][j]!=-1)
                m[i][j]=inf;
    m[s.x][s.y]=a[s.x][s.y];
}

void drum()
{
    int x,y,xx,yy,i,maxim=0;
    while(!Q.empty())
    {
        p=Q.front();
        Q.pop();
        x=p.x;
        y=p.y;
        for(i=1;i<5;++i)
        {
            xx=x+dx[i];
            yy=y+dy[i];
            if((!a[xx][yy] || a[xx][yy]>a[x][y]+1) && m[xx][yy]>-1)
            {
                a[xx][yy]=a[x][y]+1;
                if(a[xx][yy]>maxim)
                    maxim=a[xx][yy];
                p.x=xx;
                p.y=yy;
                Q.push(p);
            }
        }
    }
    m[s.x][s.y]=a[s.x][s.y];
    int l=0,r=m[s.x][s.y],mid;
    curat();
    while(l<=r)
    {
        mid=(l+r)/2;
        if(bfs(mid))
        {
            sol=mid;
            l=mid+1;
        }
        else
            r=mid-1;
        curat();
    }
}

void afisare()
{
    //int x,y;
    //FILE *out=fopen("barbar.out","w");
    ofstream out("barbar.out");
    //x=f.x;
    //y=f.y;
    //if(!ok)
    //    out<<"-1\n";
        //fprintf(out,"-1\n");
    out<<sol<<'\n';
    //fprintf(out,"%d\n",m[x][y]);
    //fclose(out);
}

int main()
{
    citire();
    drum();
    afisare();
    return 0;
}