Cod sursa(job #1966654)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 15 aprilie 2017 14:28:46
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <fstream>
#include <queue>
#define VAL 1005

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

struct pozitie
{
    int l, c;
};

pozitie poz, poz2;
pozitie start, finish;

const int dl[4]={-1, 0, 1, 0};
const int dc[4]={0, -1, 0, 1};

int N, M, i, j;
int dp[VAL][VAL];
int dist[VAL][VAL];
string c[VAL];
queue <pozitie> Q;

void Get_Distances()
{
    int i;
    while (Q.empty()==false)
    {
        poz=Q.front();
        Q.pop();
        for (i=0; i<=3; i++)
        {
            poz2.l=poz.l+dl[i];
            poz2.c=poz.c+dc[i];
            if (c[poz2.l][poz2.c]!='*')
            {
                if (dist[poz2.l][poz2.c]==0 || dist[poz2.l][poz2.c]>dist[poz.l][poz.c]+1)
                {
                    dist[poz2.l][poz2.c]=dist[poz.l][poz.c]+1;
                    Q.push(poz2);
                }
            }
        }
    }
}

bool Verify(int distance)
{
    if (dist[start.l][start.c]>=distance)
    {
        int i, j;
        for (i=1; i<=N; i++)
          for (j=1; j<=M; j++)
            dp[i][j]=0;
        dp[start.l][start.c]=1;
        Q.push(start);
        while (Q.empty()==false)
        {
            poz=Q.front();
            Q.pop();
            for (i=0; i<=3; i++)
            {
                poz2.l=poz.l+dl[i];
                poz2.c=poz.c+dc[i];
                if (c[poz2.l][poz2.c]!='*' && dist[poz2.l][poz2.c]>=distance)
                {
                    if (dp[poz2.l][poz2.c]==0 || dp[poz2.l][poz2.c]>dp[poz.l][poz.c]+1)
                    {
                        dp[poz2.l][poz2.c]=dp[poz.l][poz.c]+1;
                        Q.push(poz2);
                    }
                }
            }
        }
        return dp[finish.l][finish.c]>0;
    }
    return false;
}

int Binary_Search()
{
    int be=1, en=max(N, M)+1;
    int mid, ans=-1;
    while (be<=en)
    {
        mid=(be+en) / 2;
        if (Verify(mid)==true)
        {
            ans=mid;
            be=mid+1;
        }
        else
          en=mid-1;
    }
    return ans;
}

int main()
{
    fin >> N >> M;
    for (i=1; i<=N; i++)
    {
        fin >> c[i];
        c[i]='*'+c[i]+'*';
        for (j=1; j<=M; j++)
        {
            if (c[i][j]=='D')
            {
                dist[i][j]=1;
                poz.l=i;
                poz.c=j;
                Q.push(poz);
            }
            if (c[i][j]=='I')
            {
                start.l=i;
                start.c=j;
            }
            if (c[i][j]=='O')
            {
                finish.l=i;
                finish.c=j;
            }
        }
    }
    for (i=0; i<=M+1; i++)
    {
        c[0]+='*';
        c[N+1]+='*';
    }
    Get_Distances();
    fout << Binary_Search()-1 << '\n';
    fin.close();
    fout.close();
    return 0;
}