Cod sursa(job #1541425)

Utilizator pulseOvidiu Giorgi pulse Data 4 decembrie 2015 00:35:46
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

#define PII pair<int,int>
#define pb push_back
#define mp make_pair
#define INF 2e9

const int DIM = 1005;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

int R, C;
int d[DIM][DIM];
char m[DIM][DIM], a[DIM][DIM];
queue <PII> Q;
vector <PII> drag;
PII start, finish;

void bfs(int mindist)
{
    for(int i = 1; i <= R; i++) for(int j = 1; j <= C; j++) d[i][j] = INF;
    if (mindist != INF)
    {
        for(int i = 1; i <= R; i++) for(int j = 1; j <= C; j++) a[i][j] = m[i][j];
        for(vector <PII> :: iterator it = drag.begin(); it != drag.end(); ++it)
        {
            Q.push(mp(it -> first, it -> second));
            d[it -> first][it -> second] = 0;
            //fout << it -> first << ' ' << it -> second << '\n';
        }
    }
    else
    {
        if (a[start.first][start.second] == '*')
            return;
        Q.push(start);
        d[start.first][start.second] = 0;
    }

    while (!Q.empty())
    {
        PII node = Q.front();
        Q.pop();
        //fout << "node: " << node.first << ' ' << node.second << '\n';

        for(int dir = 0; dir < 4; ++dir)
        {
            int newX = node.first + dx[dir];
            int newY = node.second + dy[dir];

            if(newX < 1 || newX > R || newY < 1 || newY > C)
                continue;
            if (mindist != INF)
            {
                if(a[newX][newY] == 'D')
                    continue;
            }
            else
            {
                if(a[newX][newY] == '*' || a[newX][newY] == 'D')
                    continue;
            }

            if(d[newX][newY] > d[node.first][node.second] + 1)
            {
                d[newX][newY] = d[node.first][node.second] + 1;

                if(mindist != INF)
                {
                    if(d[newX][newY] < mindist)
                    {
                        a[newX][newY] = '*';
                        Q.push(mp(newX, newY));
                    }
                }
                else
                    Q.push(mp(newX, newY));
            }
        }
    }
}

bool check()
{
    bfs(INF);

    if(d[finish.first][finish.second] != INF)
        return 1;
    return 0;
}

void bs()
{
    int l = 1, r = DIM * DIM;
    int sol = -1;

    while(l <= r)
    {
        int mid = (l + r) / 2;

        bfs(mid);

        /*fout << "Pentru mid = " << mid << '\n';
        for(int i = 1; i <= R; i++) {for(int j = 1; j <= C; j++) fout << a[i][j]; fout << '\n';}

        fout << '\n';*/

        if(check())
        {
            sol = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }

    fout << sol;
}

int main()
{
    fin >> R >> C;
    for(int i = 1; i <= R; ++i)
    {
        for(int j = 1; j <= C; ++j)
        {
            fin >> m[i][j];
            if(m[i][j] == 'D')
                drag.pb(mp(i, j));
            if(m[i][j] == 'I')
            {
                start.first = i;
                start.second = j;
            }
            if (m[i][j] == 'O')
            {
                finish.first = i;
                finish.second = j;
            }
        }
    }

    bs();

    return 0;
}