Mai intai trebuie sa te autentifici.

Cod sursa(job #1874848)

Utilizator FrequeAlex Iordachescu Freque Data 10 februarie 2017 14:48:26
Problema Barbar Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

struct coord
{
    int x;
    int y;
};

queue < pair <int, int > > q;
vector < pair <int, int> > v;

const int NMAX = 1000 + 5;
const int dx[] = {-1, 0, 0, 1};
const int dy[] = {0, -1, 1, 0};

coord p1, p2;

int N, M, nr_d, st, dr;
int a[NMAX][NMAX], b[NMAX][NMAX];

void Read()
{
    char x;
    fin >> N >> M;
    for (int i = 1; i <= N; ++i)
        for (int j =1; j <= M; ++j)
        {
            fin >> x;
            if (a[i][j] == '.')
                continue;
            if (x == '*')
            {
                a[i][j] = -1;
                v.push_back(make_pair(i, j));
            }
            else if (x == 'D')
            {
                ++nr_d;
                q.push(make_pair(i, j));
            }
            else if (x == 'I')
            {
                p1.x = i;
                p1.y = j;
            }
            else if (x == 'O')
            {
                p2.x = i;
                p2.y = j;
            }
        }
}

void Border()
{
    for (int i = 0; i <= N + 1; ++i)
        a[i][0] = b[i][0] = a[i][M + 1] = b[i][M + 1] = -1;

    for (int i = 0; i <= M + 1; ++i)
        a[N + 1][i] = b[N + 1][i] = a[0][i] = b[0][i] = -1;
}

void Recon()
{
    for (int i = 0; i < v.size(); ++i)
        a[v[i].first][v[i].second] = -1;
}

bool Lee(int cnt)
{
    int x, y, xn, yn;
    q.push(make_pair(p1.x, p1.y));
    while (!q.empty())
    {
        x = q.front().first;
        y = q.front().second;
        q.pop();
        for (int dir = 0; dir < 4; ++dir)
        {
            xn = x + dx[dir];
            yn = y + dy[dir];
            if (a[xn][yn] == 0 && b[xn][yn] >= cnt)
            {
                a[xn][yn] = b[x][y] + 1;
                q.push(make_pair(xn, yn));
            }
        }
    }
    if (a[p2.x][p2.y])
        return 1;
    return 0;
}

void LeeD()
{
    int x, y, xn, yn;
    while (!q.empty())
    {
        x = q.front().first;
        y = q.front().second;
        q.pop();
        for (int dir = 0; dir < 4; ++dir)
        {
            xn = x + dx[dir];
            yn = y + dy[dir];
            if (b[xn][yn] == 0)
            {
                b[xn][yn] = b[x][y] + 1;
                q.push(make_pair(xn, yn));
            }
        }
    }
}

int binSearch(int st, int dr)
{
    int ans = 0;
    while(st <= dr)
    {
        int mid = (st + dr) / 2;
        if (Lee(mid))
        {
            ans = mid;
            st = mid + 1;

        }
        else
            dr = mid - 1;
        Border();
        Recon();
    }
    return ans;
}

int main()
{
    int ans;
    Read();
    Border();
    LeeD();
   /* for (int i = 1; i <= N; ++i)
    {
        for (int j = 1; j <= M; ++j)
            cout << b[i][j] << " ";
        cout << endl;
    }*/
    st = 0; dr = min(b[p1.x][p1.y], b[p2.x][p2.y]);
    ans = binSearch(st, dr);
    if (ans)
        fout << ans - 1;
    else
        fout << -1;
}