Cod sursa(job #1536028)

Utilizator zacuscaAlex Iordache zacusca Data 25 noiembrie 2015 16:19:34
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <fstream>
#include <queue>
#include <cstring>
#define x first
#define y second

using namespace std;

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

int n, m, sol = -1;
int D[1001][1001];
int V[1001][1001];
pair <int, int> start, stop;
const int di[] = {0,1,0,-1};
const int dj[] = {1,0,-1,0};
queue < pair <int, int> > Q;

void Dragoni()
{
    while (!Q.empty())
    {
        int i = Q.front().x;
        int j = Q.front().y;
        Q.pop();

        for (int k = 0; k < 4; ++k)
        {
            int ni = i + di[k];
            int nj = j + dj[k];
            if (D[ni][nj] == -2)
            {
                D[ni][nj] = D[i][j] + 1;
                Q.push ( {ni, nj} );
            }
        }
    }
}

bool Traseu (int dist)
{
    if (D[start.x][start.y] < dist) return 0;

    Q.push (start);
    memset (V, 0, sizeof (V));
    V[start.x][start.y] = 1;
    while (!Q.empty())
    {
        int i = Q.front().x;
        int j = Q.front().y;
        Q.pop();

        for (int k = 0; k < 4; ++k)
        {
            int ni = i + di[k];
            int nj = j + dj[k];
            if (!V[ni][nj] and D[ni][nj] >= dist)
            {
                V[ni][nj] = 1;
                Q.push ( {ni, nj} );
            }
        }
    }
    return V[stop.x][stop.y];
}

void BinSearch(int &sol)
{
    if (D[start.x][start.y] == -2) sol = -1;
    else
    {
        int st = 0, dr = n * m, mij;
        while (st <= dr)
        {
            int mij = (dr + st) >> 1;
            if (Traseu (mij))
            {
                sol = mij;
                st = mij + 1;
            }
            else dr = mij - 1;
        }
    }
}

int main()
{
    in >> n >> m;

    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            D[i][j] = -2;
        }

    for (int i = 0; i <= n+1; ++i) D[i][0] = D[i][m+1] = -1;
    for (int i = 0; i <= m+1; ++i) D[0][i] = D[n+1][i] = -1;

    char c;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
        {
            in >> c;
            switch (c)
            {
            case '*' :
                D[i][j] = -1;
                break;
            case 'O' :
                stop = {i, j};
                break;
            case 'I' :
                start = {i, j};
                break;
            case 'D' :
                D[i][j] = 0;
                Q.push( {i, j} );
                break;
            }
        }

    Dragoni();

    BinSearch(sol);

    out << sol << '\n';
    out.close();
    return 0;
}