Cod sursa(job #385842)

Utilizator dead_knightTitei Paul Adrian dead_knight Data 23 ianuarie 2010 16:06:12
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.45 kb
#include<cstdio>
using namespace std;
struct nod{
    int i,j;
    nod *next;
};
int n,m,a[1005][1005],b[1005][1005],istart,jstart,istop,jstop,di[4]={0,0,-1,1},dj[4]={1,-1,0,0};
int max;
nod *p=NULL,*t=NULL;

void citire()
{
    freopen("barbar.in","r",stdin);
    char c;
    scanf("%d%d%c",&n,&m,&c);
    int i,j;
    nod *q=NULL;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            scanf("%c",&c);
            if(c=='*')
                a[i][j]=-2;
            else if(c=='.')
                a[i][j]=-1;
            else if(c=='I')
                a[i][j]=-1,istart=i,jstart=j;
            else if(c=='O')
                a[i][j]=-1,istop=i,jstop=j;
            else if(c=='D')
            {
                q=new nod;
                q->next=NULL;
                q->i=i;
                q->j=j;
                a[i][j]=0;
                if(p==NULL)
                    p=t=q;
                else
                    t->next=q,t=q;
            }
        }
        scanf("%c",&c);
    }
}

void lee1()
{
    int k,i,ii,j,jj;
    nod *st,*dr,*q;
    st=p;
    dr=t;
    while(st)
    {
        i=st->i;
        j=st->j;
        for(k=0;k<=3;k++)
        {
            ii=i+di[k];
            jj=j+dj[k];
            if(ii<=n && jj<=m && ii>=1 && jj>=1 && a[ii][jj]!=-2)
                if(a[ii][jj]==-1 || a[i][j]+1<a[ii][jj])
                {
                    a[ii][jj]=a[i][j]+1;
                    q=new nod;
                    q->i=ii;
                    q->j=jj;
                    q->next=NULL;
                    dr->next=q;
                    dr=q;
                }
        }
        t=st;
        st=st->next;
        delete t;
    }
}

int lee2()
{
    if(a[istart][jstart]>=a[istop][jstop])
        max=a[istop][jstop];
    else
        max=a[istart][jstart];
    int k,ii,jj,i,j;
    nod *st,*dr,*st2,*dr2,*q,*t;
    st=dr=new nod;
    st2=dr2=NULL;
    st->i=istart;
    st->j=jstart;
    st->next=NULL;
    dr=st;
    while(max>=0)
    {
        while(st)
        {
            i=st->i;
            j=st->j;
            for(k=0;k<=3;k++)
            {
                ii=i+di[k];
                jj=j+dj[k];
                if(ii==istop && jj==jstop)
                    return max;
                else if(ii>0 && jj>0 && ii<=n && jj<=m && a[ii][jj]>=max-1 && b[ii][jj]==0)
                {
                    b[ii][jj]=1;
                    q=new nod;
                    q->i=ii;
                    q->j=jj;
                    q->next=NULL;
                    if(a[ii][jj]>=max)
                        dr->next=q,dr=q;
                    else if(a[ii][jj]==max-1)
                    {
                        if(st2==NULL)
                            st2=dr2=q;
                        else
                            dr2->next=q,dr2=q;
                    }
                }
            }
            t=st;
            st=st->next;
            delete t;
        }
        st=st2;
        dr=dr2;
        st2=dr2=NULL;
        max--;
    }
    return -1;
}

void write()
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
            printf("%3d ",a[i][j]);
        printf("\n");
    }
    printf("%d ",a[istop][jstop]);
}

int main()
{
    freopen("barbar.out","w",stdout);
    citire();
    //write();
    lee1();
    //write();
    int x=lee2();
    printf("%d\n",x);
    return 0;
}