Cod sursa(job #1288901)

Utilizator RaduVisanRadu Visan RaduVisan Data 9 decembrie 2014 10:08:54
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int NMAX = 1010, INF = 0x3f3f3f3f;
const int DX[4] = {-1, 0, 0, 1};
const int DY[4] = {0, -1, 1, 0};

int N, M, MinDist[NMAX][NMAX], StartX, StartY, EndX, EndY;
char S[NMAX][NMAX];
bool Can[NMAX][NMAX];

void Process()
{
    queue<pair<int, int> > Q;
    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= M; ++ j)
        {
            MinDist[i][j] = INF;
            if(S[i][j] == 'D') Q.push(make_pair(i, j)), MinDist[i][j] = 0;
        }

    while(!Q.empty())
    {
        int X = Q.front().first, Y = Q.front().second;
        Q.pop();

        for(int i = 0; i < 4; ++ i)
        {
            int NextX = X + DX[i], NextY = Y + DY[i];
            if(1 <= NextX && NextX <= N && 1 <= NextY && NextY <= M && MinDist[NextX][NextY] > MinDist[X][Y] + 1 && S[NextX][NextY] != '*')
            {
                MinDist[NextX][NextY] = MinDist[X][Y] + 1;
                Q.push(make_pair(NextX, NextY));
            }
        }
    }

    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= M; ++ j)
            if(MinDist[i][j] == INF)
                MinDist[i][j] = -1;
}

bool Check(int Min)
{
    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= M; ++ j)
            Can[i][j] = 0;

    queue<pair<int, int> > Q;
    if(MinDist[StartX][StartY] >= Min)
    {
        Q.push(make_pair(StartX, StartY));
        Can[StartX][StartY] = 1;
    }

    while(!Q.empty())
    {
        int X = Q.front().first, Y = Q.front().second;
        Q.pop();

        for(int i = 0; i < 4; ++ i)
        {
            int NextX = X + DX[i], NextY = Y + DY[i];
            if(1 <= NextX && NextX <= N && 1 <= NextY && NextY <= M && !Can[NextX][NextY] && MinDist[NextX][NextY] >= Min && S[NextX][NextY] != '*')
            {
                Can[NextX][NextY] = 1;
                Q.push(make_pair(NextX, NextY));
            }
        }
    }

    return Can[EndX][EndY];
}

int main()
{
    freopen("barbar.in", "r", stdin);
    freopen("barbar.out", "w", stdout);

    scanf("%i %i\n", &N, &M);
    for(int i = 1; i <= N; ++ i)
    {
        gets(S[i] + 1);
        for(int j = 1; j <= M; ++ j)
        {
            if(S[i][j] == 'I') StartX = i, StartY = j;
            if(S[i][j] == 'O') EndX = i, EndY = j;
        }
    }

    Process();

    int Left = 0, Right = N * M, Mid, Ans = -1;
    while(Left <= Right)
    {
        Mid = (Left + Right) / 2;
        if(Check(Mid)) Ans = Mid, Left = Mid + 1;
        else Right = Mid - 1;
    }

    printf("%i\n", Ans);
}