Cod sursa(job #1404675)

Utilizator Ionut228Ionut Calofir Ionut228 Data 28 martie 2015 14:08:08
Problema Barbar Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <fstream>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

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

const int INF = 1000005;
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};

char A[1005][1005], snul[1005];
int R, C, solmax;
int xinit, yinit, xfin, yfin;
int D[1005][1005];
queue<pair<int, int> > Q, QD;
bool used[1005][1005];

void goDragon()
{
    while (!QD.empty())
    {
        int i = QD.front().first;
        int j = QD.front().second;
        QD.pop();

        for (int k = 0; k < 4; ++k)
        {
            int nowi = i + dx[k];
            int nowj = j + dy[k];

            if (nowi > R || nowi < 1 || nowj > C || nowj < 1)
                continue;
            if (A[nowi][nowj] == '*')
                continue;

            if (D[i][j] + 1 < D[nowi][nowj])
            {
                D[nowi][nowj] = D[i][j] + 1;
                QD.push(make_pair(nowi, nowj));
            }
        }
    }
}

int solve(int val)
{
    memset(used, false, sizeof(used));
    used[xinit][yinit] = true;
    Q.push(make_pair(xinit, yinit));

    while (!Q.empty())
    {
        int i = Q.front().first;
        int j = Q.front().second;
        Q.pop();

        for (int k = 0; k < 4; ++k)
        {
            int nowi = i + dx[k];
            int nowj = j + dy[k];

            if (nowi > R || nowi < 1 || nowj > C || nowj < 1)
                continue;
            if (A[nowi][nowj] == '*' || used[nowi][nowj] == true)
                continue;

            if (A[nowi][nowj] == 'O')
                return 1;
            else if (D[nowi][nowj] >= val)
            {
                used[nowi][nowj] = true;
                Q.push(make_pair(nowi, nowj));
            }
        }
    }

    return 0;
}

void cb()
{
    int lt = -1, rt = R * C + 1;
    while (rt - lt > 1)
    {
        int mid = (lt + rt) / 2;
        if (solve(mid))
        {
            solmax = mid;
            lt = mid;
        }
        else
            rt = mid;
    }
}

int main()
{
    fin >> R >> C;
    fin.getline(snul, 1005);
    for (int i = 1; i <= R; ++i)
    {
        fin.getline(A[i] + 1, 1005);
        for (int j = 1; j <= C; ++j)
        {
            D[i][j] = INF;
            if (A[i][j] == 'I')
            {
                xinit = i;
                yinit = j;
            }
            else if (A[i][j] == 'O')
            {
                xfin = i;
                yfin = j;
            }
            else if (A[i][j] == 'D')
            {
                D[i][j] = 0;
                QD.push(make_pair(i, j));
            }
        }
    }

    goDragon();

    solmax = -1;
    cb();

    fout << solmax << '\n';

    fin.close();
    fout.close();
    return 0;
}