Cod sursa(job #2123275)

Utilizator MateiTrandafirMatei Trandafir MateiTrandafir Data 6 februarie 2018 00:02:51
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <fstream>

#define N 1002

struct pos {
    int x, y, prev;
};

int a[N][N], b[N][N], st = 0, dr = -1;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};

pos q[N * N];

inline void fill(int x, int y, int type, int min) {
    if (b[x][y] != 0 || a[x][y] < 0) return;
    if (a[x][y] < type) {
        ++dr;
        q[dr].x = x;
        q[dr].y = y;
        q[dr].prev = min;
        return;
    }
    b[x][y] = min;
    for (int i = 0; i < 4; ++i) fill(x + dx[i], y + dy[i], type, min);
}

int main() {
    std::ifstream in("barbar.in");
    std::ofstream out("barbar.out");
    int i, j, n, m, x1, x2, y1, y2;
    pos start{}, end{};
    char c;
    in >> n >> m;
    ++n; ++m;
    for (i = 0; i <= n; ++i) a[i][0] = a[i][m] = b[i][0] = b[i][m] = -1;
    for (i = 0; i <= m; ++i) a[0][i] = a[n][i] = b[0][i] = b[n][i] = -1;
    --n; --m;
    for (i = 1; i <= n; ++i) {
        for (j = 1; j <= m; ++j) {
            in >> c;
            switch (c) {
                case 'I':
                    start.x = i;
                    start.y = j;
                    break;
                case 'O':
                    end.x = i;
                    end.y = j;
                    break;
                case '*':
                    a[i][j] = -1;
                    break;
                case 'D':
                    a[i][j] = 1;
                    ++dr;
                    q[dr].x = i;
                    q[dr].y = j;
                    break;
                default: break;
            }
        }
    }
    while (dr >= st) {
        x1 = q[st].x;
        y1 = q[st].y;
        ++st;
        for (i  =  0; i < 4; ++i) {
            x2 = x1 + dx[i];
            y2 = y1 + dy[i];
            if (a[x2][y2] == 0) {
                a[x2][y2] = a[x1][y1] + 1;
                ++dr;
                q[dr].x = x2;
                q[dr].y = y2;
            }
        }
    }
    st = 0; dr = 0;
    q[0] = start;
    q[0].prev = a[start.x][start.y];
    while (dr >= st) {
        fill(q[st].x, q[st].y, a[q[st].x][q[st].y], std::min(a[q[st].x][q[st].y], q[st].prev));
        ++st;
    }
    out << (b[end.x][end.y] - 1);
    return 0;
}