Cod sursa(job #1853297)

Utilizator SirbuSirbu Ioan Sirbu Data 21 ianuarie 2017 16:28:04
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <fstream>
#include <queue>
#define inf 0x3f3f3f
using namespace std;
ifstream fin ("barbar.in");
ofstream fout ("barbar.out");

int di[]={-1,1,0,0};
int dj[]={0,0,-1,1};
char v[1002][1002];
int dist[1002][1002];
int traseu[1002][1002];
int n,m,startx,starty,finalx,finaly;

queue < pair < int, int > > q;


bool ok (int i, int j)
{
    if (i<1 || i>n || j<1 || j>m || dist[i][j]==-1) return 0;
    return 1;
}



void Fill ()
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            {
                dist[i][j]=inf;
                if (v[i][j]=='D'){ q.push(make_pair(i,j)); dist[i][j] = 0;}
                if (v[i][j]=='*') dist[i][j]=-1;

            }
    while (!q.empty())
    {
        int i=q.front().first;
        int j=q.front().second;
        q.pop();
        for (int k=0;k<4;k++)
        {
            int vecini=i+di[k];
            int vecinj=j+dj[k];
            if (ok(vecini,vecinj) && dist[i][j]+1 < dist[vecini][vecinj])
            {
                dist[vecini][vecinj]=dist[i][j]+1;
                q.push(make_pair(vecini,vecinj));
            }
        }



    }
}

bool Lee (int dmax)
{
    if (dist[startx][starty]<dmax) return 0;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            {
                if (v[i][j]=='*') traseu[i][j]=-1;
                else traseu[i][j]=inf;
            }
    q.push(make_pair(startx,starty));
    traseu[startx][starty] = 0;

    while (!q.empty())
    {
        int i=q.front().first;
        int j=q.front().second;
        q.pop();
        for (int k=0;k<4;k++)
        {
            int vecini=i+di[k];
            int vecinj=j+dj[k];
            if (ok(vecini,vecinj) && traseu[i][j]+1<traseu[vecini][vecinj] && dist[vecini][vecinj]>=dmax)
            {
                traseu[vecini][vecinj]=traseu[i][j]+1;
                q.push(make_pair(vecini,vecinj));
            }
        }
    }
    if (traseu[finalx][finaly]!=inf) return 1;
    return 0;

}


int main()
{
    fin >> n >> m;
    for (int i=1;i<=n;i++)
    {
        fin >> (v[i] + 1);
        for (int j=1;j<=m;j++)
        {
            if (v[i][j]=='I') {startx=i; starty=j;}
            if (v[i][j]=='O') {finalx=i; finaly=j;}
        }
    }
    Fill();
    int st=1;
    int dr=1000000;
    int sol=-1;
    while (st<=dr)
    {
        int mij=(st+dr)/2;
        if (Lee(mij)) {st=mij+1; sol=mij;}
        else dr=mij-1;
    }
    fout << sol << "\n";
    return 0;
}