Cod sursa(job #1912254)

Utilizator Harsa_AndreiHarsa Andrei Harsa_Andrei Data 8 martie 2017 00:19:14
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <fstream>
#include <queue>
#define INF 0x3f3f3f3f

using namespace std;

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

int ml[]={1,-1,0,0};
int mc[]={0,0,1,-1};

queue <pair <int, int> > q;

char M[1002][1002];
int Dragoni[1002][1002];
int Drum[1002][1002];

bool ok(int i,int j,int n,int m)
{
    if(i < 1 || i > n || j < 1 || j > m)
        return false;
    return true;
}

void Dist(int n, int m)
{
    while(!q.empty())
    {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i=0; i < 4; i++)
        {
            int xx=x + ml[i];
            int yy=y + mc[i];
            if(ok(xx, yy, n, m)&&Dragoni[xx][yy] != -1&&Dragoni[xx][yy] > Dragoni[x][y] + 1)
            {
                Dragoni[xx][yy]=Dragoni[x][y] + 1;
                q.push(make_pair(xx,yy));
            }
        }
    }
}

bool Lee(int n,int m,int dist)
{
    int starti, startj, stopi, stopj;
    for(int i=1; i <= n; i++)
        for(int j=0; j < m; j++)
        {
            if(M[i][j] == '*')
                Drum[i][j+1] = -1;
            else
                if(M[i][j] == 'I')
                {
                    starti=i;
                    startj=j+1;
                    Drum[i][j+1]=0;
                    q.push(make_pair(i,j+1));
                }
            else
                if(M[i][j] == 'O')
                {
                    stopi=i;
                    stopj=j+1;
                    Drum[i][j+1]=INF;
                }
            else
                Drum[i][j+1]=INF;
        }
    if (Dragoni[starti][startj]<dist) return 0;
    else
    {
        while(!q.empty())
        {
            int x = q.front().first;
            int y = q.front().second;
            q.pop();
            for(int i=0; i < 4; i++)
            {
                int xx=x + ml[i];
                int yy=y + mc[i];
                if(ok(xx, yy, n, m)&&Drum[xx][yy] != -1&&Drum[xx][yy] > Drum[x][y] + 1&&Dragoni[xx][yy] >= dist)
                {
                    Drum[xx][yy]=Drum[x][y] + 1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        if (Drum[stopi][stopj]!=INF) return 1;
        return 0;
    }
}

int main()
{
    int n, m;
    fin >> n >> m;
    for(int i = 1; i <= n; i++)
        fin >> M[i];
    for(int i=1; i <= n; i++)
        for(int j=0; j < m; j++)
        {
            if(M[i][j] == '*')
                Dragoni[i][j+1] = -1;
            else
                if(M[i][j] == 'D')
                {
                    Dragoni[i][j+1] = 0;
                    q.push(make_pair(i, j+1));
                }
            else
                Dragoni[i][j+1]=INF;
        }
    Dist(n, m);
    int st=1;
    int dr=1000000;
    int sol=-1;
    while (st<=dr)
    {
        int mij=(st+dr)/2;
        if (Lee(n,m,mij)) {st=mij+1; sol=mij;}
        else dr=mij-1;
    }
    fout << sol << "\n";
    return 0;
}