Cod sursa(job #2716434)

Utilizator lucamLuca Mazilescu lucam Data 5 martie 2021 10:30:04
Problema Barbar Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <fstream>
#include <queue>

std::ifstream in("barbar.in");
std::ofstream out("barbar.out");

const int dl[] = {-1, 0, 0, 1};
const int dc[] = {0, -1, 1, 0};

const int N = 1000;
int a[N + 2][N + 2];
char line[N + 1];
int r, c;
struct Pos {
    int l, c;
};
Pos start, finish;
std::queue<Pos> q, q2;

void bordare() {
    for (int i = 0; i <= r + 1; ++i) {
        a[i][0] = a[i][c + 1] = -1;
    }
    for (int j = 0; j <= c + 1; ++j) {
        a[0][j] = a[r + 1][j] = -1;
    }
}

void lee_dragoni() {
    while (!q.empty()) {
        Pos cur = q.front();
        q.pop();
        for (int i = 0; i < 4; ++i) {
            Pos nou = {cur.l + dl[i], cur.c + dc[i]};
            if (a[nou.l][nou.c] == 0) {
                a[nou.l][nou.c] = a[cur.l][cur.c] + 1;
                q.push(nou);
            }
        }
    }
}

int lee_sol() {
    std::queue<Pos> *primary = &q, *secondary = &q2;
    int pivot;
    Pos dest;
    if (a[start.l][start.c] < a[finish.l][finish.c]) {
        primary->push(start);
        dest = finish;
        pivot = a[start.l][start.c];
    }
    else {
        primary->push(finish);
        dest = start;
        pivot = a[finish.l][finish.c];
    }
    while (!primary->empty() || !secondary->empty()) {
        while (!primary->empty()) {
            Pos cur = primary->front();
            primary->pop();
            for (int i = 0; i < 4; ++i) {
                Pos nou = {cur.l + dl[i], cur.c + dc[i]};
                if (a[nou.l][nou.c] == -1) {
                    continue;
                }
                if (nou.l == dest.l && nou.c == dest.c) {
                    return pivot;
                }
                if (a[nou.l][nou.c] < pivot) {
                    secondary->push(nou);
                }
                else {
                    primary->push(nou);
                }
                a[nou.l][nou.c] = -1;
            }
        }
        --pivot;
        std::swap(primary, secondary);
    }
    return 0;
}

int main() {
    in >> r >> c;
    bordare();
    for (int i = 0; i < r; ++i) {
        in.getline(line, N);
        for (int j = 0; j < c; ++j) {
            switch (line[j]) {
            case 'I':
                start = {i + 1, j + 1};
                break;
            case 'O':
                finish = {i + 1, j + 1};
                break;
            case '*':
                a[i + 1][j + 1] = -1;
                break;
            case 'D':
                q.push({i + 1, j + 1});
                a[i + 1][j + 1] = 1;
            }
        }
    }
    lee_dragoni();
    out << lee_sol() - 1;
}