Cod sursa(job #1410813)

Utilizator andreea_zahariaAndreea Zaharia andreea_zaharia Data 31 martie 2015 11:59:24
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include <cstdio>

#define N 1000
#define OBSTACOL -1
#define DRAGON -2

struct poz {int lin, col;} coada[N * N];
int inc, sf;
int dl[] = {-1, 0, 1, 0}, dc[] = {0, 1, 0, -1};
int dragoni[N +2][N +2], paftenie[N +2][N +2];
poz start, stop;
int n, m;

void bordare (int a[][N+2]) {
    for (int i = 0; i <= n +1; i++) {
        a[i][0] = a[i][m +1] = OBSTACOL;
    }
    for (int i = 0; i <= m +1; i++) {
        a[0][i] = a[n +1][i] = OBSTACOL;
    }
}

void leeDragoni () {
    inc = 1;

    while (inc <= sf) {
        for (int i = 0; i < 4; i++) {
            int x = coada[inc].lin + dl[i];
            int y = coada[inc].col + dc[i];

            if ( !dragoni[x][y]) {
                coada[++sf].lin = x;
                coada[sf].col = y;
                dragoni[x][y] = dragoni[coada[inc].lin][coada[inc].col] +1;
            }
        }

        inc++;
    }
}

void leePaftenie (int conditie) {
    inc = 1; sf = 0;
    coada[++sf] = start;

    while (inc <= sf) {
        for (int i = 0; i < 4; i++) {
            int x = coada[inc].lin + dl[i];
            int y = coada[inc].col + dc[i];

            if ( !paftenie[x][y] && dragoni[x][y] - 1 >= conditie) {
                coada[++sf].lin = x;
                coada[sf].col = y;
                paftenie[x][y] = paftenie[coada[inc].lin][coada[inc].col] +1;
            }
        }

        inc++;
    }
}

void stergere (int a[][N +2]) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j] > 0) {
                a[i][j] = 0;
            }
        }
    }
}

int main () {
    freopen ("barbar.in", "r", stdin);
    freopen ("barbar.out", "w", stdout);

    char c;
    scanf ("%d%d ", &n, &m);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf ("%c", &c);
            switch (c) {
                case 'I': start.lin = i; start.col = j; break;
                case 'O': stop.lin = i; stop.col = j; break;
                case 'D': coada[++sf].lin = i; coada[sf].col = j; dragoni[i][j] = 1; paftenie[i][j] = OBSTACOL; break;
                case '*': dragoni[i][j] = OBSTACOL; paftenie[i][j] = OBSTACOL;
            }
        }
        scanf ("%c", &c);
    }

    bordare (dragoni);
    leeDragoni ();

    bordare (paftenie);
    int X, pas;
    for (pas = 1 << 20, X = 0; pas >= 1; pas >>= 1) {
        if (X + pas <= dragoni[start.lin][start.col] - 1) {
            leePaftenie (X + pas);
            if (paftenie[stop.lin][stop.col]) {
                X += pas;
            }
            stergere (paftenie);
        }
    }
    if ( !X) {
        printf ("-1\n");
    }
    else {
        printf ("%d\n", X);
    }

    return 0;
}