Cod sursa(job #1595237)

Utilizator NicusorTelescu Nicolae Nicusor Data 10 februarie 2016 07:59:24
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.68 kb
#include <cstdio>
#include <iostream>
#include <string>
#include <queue>

using namespace std;

string a;

int n,m;
int inc,sf;
int temnita[1002][1002];
int drum[1002][1002];
bool se_poate[1002][1002];

queue <int> coada;

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;
                coada.push(i*10000+j+1);
            }
        }
    }
    while (!coada.empty())
    {
        int l,c;
        l=coada.front()/10000;
        c=coada.front()%10000;
        if (temnita[l+1][c]==0 || temnita[l+1][c]>temnita[l][c]+1)
        {
            temnita[l+1][c]=temnita[l][c]+1;
            coada.push((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;
            coada.push((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;
            coada.push(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;
            coada.push(l*10000+c-1);
        }
        coada.pop();
    }
    coada.push(inc);
    drum[inc/10000][inc%10000]=temnita[inc/10000][inc%10000];
    while (!coada.empty())
    {
        int l,c;
        l=coada.front()/10000;
        c=coada.front()%10000;
        if (drum[l-1][c]<drum[l][c] && drum[l-1][c]!=-1)
        {
            if (temnita[l-1][c]>drum[l-1][c])
            {
                drum[l-1][c]=drum[l][c];
                if (temnita[l-1][c]<drum[l-1][c])
                    drum[l-1][c]=temnita[l-1][c];
                coada.push((l-1)*10000+c);
            }
        }
        if (drum[l+1][c]<drum[l][c] && drum[l+1][c]!=-1)
        {
            if (temnita[l+1][c]>drum[l+1][c])
            {
                drum[l+1][c]=drum[l][c];
                if (temnita[l+1][c]<drum[l+1][c])
                    drum[l+1][c]=temnita[l+1][c];
                coada.push((l+1)*10000+c);
            }
        }
        if (drum[l][c+1]<drum[l][c] && drum[l][c+1]!=-1)
        {
            if (temnita[l][c+1]>drum[l][c+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];
                coada.push(l*10000+c+1);
            }
        }
        if (drum[l][c-1]<drum[l][c] && drum[l][c-1]!=-1)
        {
            if (temnita[l][c-1]>drum[l][c-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];
                coada.push(l*10000+c-1);
            }
        }
        coada.pop();
    }
    coada.push(inc);
    while (!coada.empty())
    {
        int l,c;
        l=coada.front()/10000;
        c=coada.front()%10000;
        if (se_poate[l+1][c]==false)
        {
            se_poate[l+1][c]=true;
            coada.push((l+1)*10000+c);
        }
        if (se_poate[l-1][c]==false)
        {
            se_poate[l-1][c]=true;
            coada.push((l-1)*10000+c);
        }
        if (se_poate[l][c+1]==false)
        {
            se_poate[l][c+1]=true;
            coada.push(l*10000+c+1);
        }
        if (se_poate[l][c-1]==false)
        {
            se_poate[l][c-1]=true;
            coada.push(l*10000+c-1);
        }
        coada.pop();
    }
    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);
    }
}