Cod sursa(job #997972)

Utilizator poptibiPop Tiberiu poptibi Data 15 septembrie 2013 12:57:00
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

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

int N, M, StartX, StartY, EndX, EndY, D[NMAX][NMAX], Used[NMAX][NMAX];
char Mat[NMAX][NMAX];
bool InQueue[NMAX][NMAX];

void FindNearest()
{
    memset(D, INF, sizeof(D));
    queue<pair<int, int> > Q;

    for(int i = 1; i <= N; ++ i)
        for(int j = 1; j <= M; ++ j)
        {
            InQueue[i][j] = 0;
            if(Mat[i][j] == 'D')
            {
                Q.push(make_pair(i, j));
                D[i][j] = 0;
                InQueue[i][j] = 1;
            }
        }

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

        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 && Mat[NextX][NextY] != '*' && D[NextX][NextY] > D[X][Y] + 1)
            {
                D[NextX][NextY] = D[X][Y] + 1;
                if(!InQueue[NextX][NextY]) InQueue[NextX][NextY] = 1, Q.push(make_pair(NextX, NextY));
            }
        }
    }
}

bool Check(int MaxDist)
{
    memset(Used, 0, sizeof(Used));
    queue<pair<int, int> > Q;
    Q.push(make_pair(StartX, StartY));
    Used[StartX][StartY] = 1;

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

        if(X == EndX && Y == EndY) return 1;

        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 && Mat[NextX][NextY] != '*' && !Used[NextX][NextY] && D[NextX][NextY] >= MaxDist)
            {
                Used[NextX][NextY] = 1;
                Q.push(make_pair(NextX, NextY));
            }
        }
    }
    return 0;
}

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(Mat[i] + 1);
        for(int j = 1; j <= M; ++ j)
        {
            if(Mat[i][j] == 'I') StartX = i, StartY = j;
            if(Mat[i][j] == 'O') EndX = i, EndY = j;
        }
    }

    FindNearest();

    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);

    return 0;
}