Cod sursa(job #977299)

Utilizator manutrutaEmanuel Truta manutruta Data 25 iulie 2013 15:23:04
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.93 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <queue>
#include <bitset>
using namespace std;

#define MAXN 1010
#define MAXM

int n, m;
int a[MAXN][MAXN];
bitset<MAXN> viz[MAXN];
int startx, starty, finex, finey;
queue<pair<int, int> > coada;
int d[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};

void lee()
{
    while (!coada.empty()) {
        int px, py;

        px = coada.front().first;
        py = coada.front().second;
        coada.pop();

        for (int i = 0; i < 4; i++) {
            int nx, ny;

            nx = px + d[i][0];
            ny = py + d[i][1];

            if (a[nx][ny] == -1 ||
                nx <= 0 || ny <= 0 ||
                nx > n || ny > m) {
                continue;
            }

            if (a[nx][ny] > a[px][py] + 1) {
                a[nx][ny] = a[px][py] + 1;
                coada.push(make_pair(nx, ny));
            }
        }
    }
}

int check(int x)
{
    for (int i = 1; i <= n; ++i) {
        viz[i].reset();
    }

    viz[startx][starty] = 1;

    coada.push(make_pair(startx, starty));

    while (!coada.empty()) {
        int px, py;
        px = coada.front().first;
        py = coada.front().second;
        coada.pop();

        for (int i = 0; i < 4; i++) {
            int nx, ny;
            nx = px + d[i][0];
            ny = py + d[i][1];

            if (nx <= 0 || ny <= 0 || nx > n || ny > m) {
                continue;
            }

            if (a[nx][ny] == -1) {
                continue;
            }

            if (a[nx][ny] >= x && !viz[nx][ny]) {
                viz[nx][ny] = true;
                coada.push(make_pair(nx, ny));
            }
        }
    }

    return viz[finex][finey];
}

int main()
{
    FILE * fin = fopen("barbar.in", "r");
    FILE * fout = fopen("barbar.out", "w");

    memset(a, 0x3F, sizeof(a));

    fscanf(fin, "%d %d\n", &n, &m);

    char aux[MAXN];
    for (int i = 1; i <= n; i++) {
        fgets(aux + 1, sizeof(aux), fin);
        for (int j = 1; j <= m; j++) {
            switch (aux[j]) {
                case '*':
                    a[i][j] = -1;
                    break;
                case 'O':
                    startx = i;
                    starty = j;
                    break;
                case 'I':
                    finex = i;
                    finey = j;
                    break;
                case 'D':
                    a[i][j] = 0;
                    coada.push(make_pair(i, j));
                    break;
            }
        }
    }

    lee();
    int a = 0, b = (m < n) ? n : m, mdl, last = -1;
    while (a <= b) {
        mdl = a + (b - a) / 2;
        if (check(mdl)) {
            a = mdl + 1;
            last = mdl;
        } else {
            b = mdl - 1;
        }
    }

    fprintf(fout, "%d\n", last);

    fclose(fin);
    fclose(fout);
    return 0;
}