Cod sursa(job #179384)

Utilizator M@2Te4iMatei Misarca M@2Te4i Data 15 aprilie 2008 20:56:10
Problema Barbar Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.77 kb
#include <fstream>
#include <queue>

using namespace std;

int n,m,a[1001][1001],il,ic,pl,pc,b[1001][1001],e[1001][1001];
queue <int> w,q;
int z[4]={0,0,-1,1};
int x[4]={1,-1,0,0};

void citire()
{
    freopen("barbar.in","r",stdin);
    scanf("%d%d\n", &n, &m);
    char s[1000];
    for (int i=1; i<=n; i++)
    {
        fgets(s,1000,stdin);
        for (int j=0; j<m; j++)
            if (s[j]=='D')
            {
                a[i][j+1]=1;
                q.push(i);
                w.push(j+1);
            }
            else
            if (s[j]=='*')
                a[i][j+1]=b[i][j+1]=-1;
            else
            if (s[j]=='O')
            {
                il=i;
                ic=j+1;
//                b[i][j+1]=-2;
            }
            else
            if (s[j]=='I')
            {
                pl=i;
                pc=j+1;
                b[i][j+1]=-3;
                e[i][j]=1;
            }
    }
}

void dragon()
{
    int i,j,ii,jj;
    while (q.size()>0)
    {
        ii=q.front();
        jj=w.front();
        q.pop();
        w.pop();
        i=ii-1;
        j=jj;
        while (i>0)
        {
            if (a[i][j]<0)
                break;
            else
            if (a[i][j]>a[i+1][j]+1 || a[i][j]==0)
                a[i][j]=a[i+1][j]+1;
            --i;
        }
        i=ii;
        j=jj-1;
        while (j>0)
        {
            if (a[i][j]<0)
                break;
            else
            if (a[i][j]>a[i][j+1]+1 || a[i][j]==0)
                a[i][j]=a[i][j+1]+1;
            --j;
        }
        i=ii+1;
        j=jj;
        while (i<=n)
        {
            if (a[i][j]<0)
                break;
            else
            if (a[i][j]>a[i-1][j]+1 || a[i][j]==0)
                a[i][j]=a[i-1][j]+1;
            ++i;
        }
        i=ii;
        j=jj+1;
        while (j<=m)
        {
            if (a[i][j]<0)
                break;
            else
            if (a[i][j]>a[i][j-1]+1 || a[i][j]==0)
                a[i][j]=a[i][j-1]+1;
            ++j;
        }
    }
}

void lee()
{
    q.push(pl);
    w.push(pc);
    int l,c,o;
    while (q.size()>0)
    {
        l=q.front();
        c=w.front();
        q.pop();
        w.pop();
        o=0;
        if (l>0 && l<=n && c>0 && c<=m)
        {
            for (int i=0; i<4; i++)
            {
                if (b[l+z[i]][c+x[i]]==-1 || e[l+z[i]][c+x[i]]==1)
                    continue;
                if (b[l+z[i]][c+x[i]]==0)
                {
                    b[l+z[i]][c+x[i]]=b[l][c];
                    e[l+z[i]][c+x[i]]=1;
                    o=1;
                }
                if (a[l+z[i]][c+x[i]]>0 && (b[l+z[i]][c+x[i]]>a[l+z[i]][c+x[i]] || b[l+z[i]][c+x[i]]<0))
                {
                    b[l+z[i]][c+x[i]]=a[l+z[i]][c+x[i]];
                    e[l+z[i]][c+x[i]]=1;
                    o=1;
                }
                //else
                if (b[l+z[i]][c+x[i]]<b[l][c])
                {
                    b[l+z[i]][c+x[i]]=b[l][c];
                    e[l+z[i]][c+x[i]]=1;
                    o=1;
                }
                if (o)
                {
                    q.push(l+z[i]);
                    w.push(c+x[i]);
                }
            }
        }
    }
}

int main()
{
    citire();
    dragon();
    lee();
    freopen("barbar.out","w",stdout);
    printf("%d\n",b[il][ic]-1);
    /*for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=m; j++)
            printf("%3d",b[i][j]);
        printf("\n");
    }
    printf("\n");
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=m; j++)
            printf("%3d",a[i][j]);
        printf("\n");
    }*/
    return 0;
}