Cod sursa(job #1541341)

Utilizator diana97Diana Ghinea diana97 Data 3 decembrie 2015 22:28:08
Problema Barbar Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;

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

const int DIR = 4;
const int NMAX = 1000 + 1;

int n, m;

int di[] = {-1, 0, 1,  0};
int dj[] = { 0, 1, 0, -1};

pair <int, int> inceput, sfarsit;

pair <int, int> dragon[NMAX * NMAX];
int cost[NMAX][NMAX];
bool viz[NMAX][NMAX];

queue < pair <int, int> > Q;


void citeste() {
    char c;

    f >> n >> m;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            f >> c;
            if (c == 'I') {
                inceput.first = i;
                inceput.second = j;
                continue;
            }
            if (c == 'O') {
                sfarsit.first = i;
                sfarsit.second = j;
                continue;
            }
            if (c == 'D') {
                Q.push(make_pair(i, j));
                cost[i][j] = 1;
            }
        }
}

inline bool is_inside(int i, int j) {
    if (i == 0 || i == n + 1) return false;
    if (j == 0 || j == m + 1) return false;
    return true;
}

void init() {
    int i, j, i_next, j_next;
    pair <int, int> p;

    while(!Q.empty()) {
        p = Q.front();
        Q.pop();

        i = p.first;
        j = p.second;

        for (int k = 0; k < DIR; k++) {
            i_next = i + di[k];
            j_next = j + dj[k];

            if (is_inside(i_next, j_next) && cost[i_next][j_next] == 0) {
                cost[i_next][j_next] = cost[i][j] + 1;
                Q.push(make_pair(i_next, j_next));
            }
        }
    }
}

void uita() {
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            viz[i][j] = false;
}

bool exista_drum(int dmin) {
    int i, j, i_next, j_next;
    pair <int, int> p;
    queue < pair <int, int> > Q;
    Q.push(inceput);

    uita();
    viz[inceput.first][inceput.second] = true;

    while (!Q.empty()) {
        p = Q.front();
        Q.pop();

        i = p.first;
        j = p.second;

        if (p == sfarsit) return true;

        for (int k = 0; k < DIR; k++) {
            i_next = i + di[k];
            j_next = j + dj[k];

            if (is_inside(i_next, j_next) && !viz[i_next][j_next] && cost[i_next][j_next] >= dmin) {
                viz[i_next][j_next] = true;
                Q.push(make_pair(i_next, j_next));
            }
        }
    }


    return viz[sfarsit.first][sfarsit.second];
}

void rezolva() {
    int st = 1, dr = n * m + 1, m, sol = 0;

    while (st <= dr) {
        m = (st + dr) / 2;
        if (exista_drum(m)) {
            sol = m;
            st = m + 1;
        }
        else dr = m - 1;
    }

    g << sol - 1 << '\n';
}

int main() {
    citeste();
    init();
    rezolva();

    return 0;
}