Cod sursa(job #1594611)

Utilizator NicusorTelescu Nicolae Nicusor Data 9 februarie 2016 16:55:11
Problema Barbar Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.55 kb
#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

string a;

int n,m;
int dragoni[4000002],nr_dragoni,inc,sf;
int temnita[1002][1002];
int drum[1002][1002];
bool se_poate[1001][1001];

void bordare()
{
    for (int i=0;i<=n+1;i++)
    {
        if (i==0 || i==n+1)
            for (int j=0;j<=m+1;j++)
            {
                temnita[i][j]=-1;
                drum[i][j]=-1;
                se_poate[i][j]=true;
            }
        else
        {
            drum[i][0]=-1;
            drum[i][m+1]=-1;
            temnita[i][0]=-1;
            temnita[i][m+1]=-1;
            se_poate[i][0]=true;
            se_poate[i][m+1]=true;
        }
    }
}

int main()
{
    freopen("barbar.in","r",stdin);
    freopen("barbar.out","w",stdout);
    scanf("%d %d\n",&n,&m);
    bordare();
    for (int i=1;i<=n;i++)
    {
        getline(cin,a);
        for (int j=0;j<a.size();j++)
        {
            if (a[j]=='I')
                inc=i*10000+j+1;
            if (a[j]=='O')
                sf=i*10000+j+1;
            if (a[j]=='*')
            {
                temnita[i][j+1]=-1;
                se_poate[i][j+1]=true;
            }
            if (a[j]=='D')
            {
                temnita[i][j+1]=1;
                dragoni[++nr_dragoni]=i*10000+j+1;
            }
        }
    }
    int inceput=1;
    while (inceput<=nr_dragoni)
    {
        int l,c;
        l=dragoni[inceput]/10000;
        c=dragoni[inceput]%10000;
        if (temnita[l+1][c]==0 || temnita[l+1][c]>temnita[l][c]+1)
        {
            temnita[l+1][c]=temnita[l][c]+1;
            dragoni[++nr_dragoni]=(l+1)*10000+c;
        }
        if (temnita[l-1][c]==0 || temnita[l-1][c]>temnita[l][c]+1)
        {
            temnita[l-1][c]=temnita[l][c]+1;
            dragoni[++nr_dragoni]=(l-1)*10000+c;
        }
        if (temnita[l][c+1]==0 || temnita[l][c+1]>temnita[l][c]+1)
        {
            temnita[l][c+1]=temnita[l][c]+1;
            dragoni[++nr_dragoni]=l*10000+c+1;
        }
        if (temnita[l][c-1]==0 || temnita[l][c-1]>temnita[l][c]+1)
        {
            temnita[l][c-1]=temnita[l][c]+1;
            dragoni[++nr_dragoni]=l*10000+c-1;
        }
        inceput++;
    }
    inceput=1;
    nr_dragoni=1;
    dragoni[nr_dragoni]=inc;
    drum[inc/10000][inc%10000]=temnita[inc/10000][inc%10000];
    while (inceput<=nr_dragoni)
    {
        int l,c;
        l=dragoni[inceput]/10000;
        c=dragoni[inceput]%10000;
        if (drum[l-1][c]<drum[l][c] && drum[l-1][c]!=-1)
        {
            drum[l-1][c]=drum[l][c];
            if (temnita[l-1][c]<drum[l-1][c])
                drum[l-1][c]=temnita[l-1][c];
            dragoni[++nr_dragoni]=(l-1)*10000+c;
        }
        if (drum[l+1][c]<drum[l][c] && drum[l+1][c]!=-1)
        {
            drum[l+1][c]=drum[l][c];
            if (temnita[l+1][c]<drum[l+1][c])
                drum[l+1][c]=temnita[l+1][c];
            dragoni[++nr_dragoni]=(l+1)*10000+c;
        }
        if (drum[l][c+1]<drum[l][c] && drum[l][c+1]!=-1)
        {
            drum[l][c+1]=drum[l][c];
            if (temnita[l][c+1]<drum[l][c+1])
                drum[l][c+1]=temnita[l][c+1];
            dragoni[++nr_dragoni]=l*10000+c+1;
        }
        if (drum[l][c-1]<drum[l][c] && drum[l][c-1]!=-1)
        {
            drum[l][c-1]=drum[l][c];
            if (temnita[l][c-1]<drum[l][c-1])
                drum[l][c-1]=temnita[l][c-1];
            dragoni[++nr_dragoni]=l*10000+c-1;
        }
        inceput++;
    }
    inceput=1;
    nr_dragoni=1;
    dragoni[1]=inc;
    while (inceput<=nr_dragoni)
    {
        int l,c;
        l=dragoni[inceput]/10000;
        c=dragoni[inceput]%10000;
        if (se_poate[l+1][c]==false)
        {
            se_poate[l+1][c]=true;
            dragoni[++nr_dragoni]=(l+1)*10000+c;
        }
        if (se_poate[l-1][c]==false)
        {
            se_poate[l-1][c]=true;
            dragoni[++nr_dragoni]=(l-1)*10000+c;
        }
        if (se_poate[l][c+1]==false)
        {
            se_poate[l][c+1]=true;
            dragoni[++nr_dragoni]=l*10000+c+1;
        }
        if (se_poate[l][c-1]==false)
        {
            se_poate[l][c-1]=true;
            dragoni[++nr_dragoni]=l*10000+c-1;
        }
        inceput++;
    }
    if (se_poate[sf/10000][sf%10000]==false)
        printf("-1");
    else
    {
        if (drum[sf/10000][sf%10000]==0)
            printf("0");
        else
            printf("%d",drum[sf/10000][sf%10000]-1);
    }
}