Cod sursa(job #1000377)

Utilizator florin.elfusFlorin Elfus florin.elfus Data 22 septembrie 2013 19:38:58
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int d1[] = {1, 0, -1, 0},
          d2[] = {0, 1, 0, -1};

inline int abs(int x)
{
    return x < 0 ? -x : x;
}

bool Test(int x);
bool Ok(pair<int, int> p);

int n, m;
queue<pair<int, int> > dr, q;
vector<pair<int, int> > d;
int can[1001][1001], ncan[1001][1001];
pair<int, int> st, fn;
int res = -1;

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

    fin >> n >> m;

    char str[1005];
    fin.getline(str, 1002);

    for (int i = 1; i <= n; ++i)
    {
        fin.getline(str, 1002);
        for (int j = m; j >= 1; --j)
        {
            str[j] = str[j - 1];
            if (str[j] == 'D')
                d.push_back(make_pair(i, j)), can[i][j] = -1;
            else if (str[j] == '*')
                can[i][j] = -1;
            else if (str[j] == 'I')
                st = make_pair(i, j);
            else if (str[j] == 'O')
                fn = make_pair(i, j);
        }
    }

    int aux = max(n, m), step;
    for (step = 1; (step << 1) <= aux; step <<= 1);
    for (int i = 0; step; step >>= 1)
        if (i + step <= aux && Test(i + step))
            i += step, res = i;

    fout << res;

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

bool Test(int x)
{
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            ncan[i][j] = can[i][j];

    for (int i = 0; i < d.size(); ++i)
        dr.push(d[i]);
    while (!dr.empty())
    {
        pair<int, int> now = dr.front(), aux; dr.pop();
        if (abs(ncan[now.first][now.second]) == x)
            continue;

        for (int k = 0; k < 4; ++k)
        {
            aux = now;
            aux.first += d1[k], aux.second += d2[k];
            if (Ok(aux))
            {
                ncan[aux.first][aux.second] = ncan[now.first][now.second] - 1;
                dr.push(aux);
            }
        }
    }

    if (ncan[st.first][st.second] != 0) return false;
    ncan[st.first][st.second] = 1;

    while (!q.empty()) q.pop();
    q.push(st);
    while (!q.empty())
    {
        pair<int, int> now = q.front(), aux; q.pop();

        for (int k = 0; k < 4; ++k)
        {
            aux = now;
            aux.first += d1[k], aux.second += d2[k];
            if (Ok(aux))
            {
                ncan[aux.first][aux.second] = ncan[now.first][now.second];
                q.push(aux);

                if (aux == fn) return true;
            }
        }
    }

    return false;
}

bool Ok(pair<int, int> p)
{
    if (p.first < 1 || p.first > n || p.second < 1 || p.second > m) return false;
    if (ncan[p.first][p.second] != 0) return false;
    return true;
}