Cod sursa(job #2080699)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 3 decembrie 2017 14:08:35
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <bits/stdc++.h>
using namespace std;

constexpr int DIM = 1005;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, 1, -1};

int line_count, column_count, init_x, init_y, final_x, final_y;
int matrix[DIM][DIM];
queue< pair<int, int> > que;

void lee_dragons() {
    while (!que.empty()) {
        int x, y;
        tie(x, y) = que.front();
        que.pop();

        for (int dir = 0; dir < 4; ++dir) {
            int nxt_x = x + dx[dir];
            int nxt_y = y + dy[dir];

            if (nxt_x >= 0 && nxt_x < line_count && nxt_y >= 0 && nxt_y < column_count && matrix[nxt_x][nxt_y] == 0) {
                que.push({nxt_x, nxt_y});
                matrix[nxt_x][nxt_y] = matrix[x][y] + 1;
            }
        }
    }
}

bool temp_matrix[DIM][DIM];
bool lee_verify(int min_dist) {
    while (!que.empty())
        que.pop();
    que.push({init_x, init_y});

    for (int i = 0; i < line_count; ++i)
        for (int j = 0; j < column_count; ++j)
            temp_matrix[i][j] = (matrix[i][j] == -1);
    temp_matrix[init_x][init_y] = true;

    bool found = false;
    while (!que.empty() && !found) {
        int x, y;
        tie(x, y) = que.front();
        que.pop();

        for (int dir = 0; dir < 4; ++dir) {
            int nxt_x = x + dx[dir];
            int nxt_y = y + dy[dir];

            if (nxt_x >= 0 && nxt_x < line_count && nxt_y >= 0 && nxt_y < column_count
                && matrix[nxt_x][nxt_y] >= min_dist && !temp_matrix[nxt_x][nxt_y]) {
                que.push({nxt_x, nxt_y});
                temp_matrix[nxt_x][nxt_y] = true;

                if (nxt_x == final_x && nxt_y == final_y) {
                    found = true;
                    break;
                }
            }
        }
    }

    return found;
}

int binary_search_solution() {
    int left = 1, right = line_count * column_count;
    bool can_finish = false;
    while (left <= right) {
        int middle = (left + right) / 2;

        if (lee_verify(middle) && matrix[init_x][init_y] >= middle) {
            left = middle + 1;
            can_finish = true;
        } else
            right = middle - 1;
    }

    return (can_finish ? right-1 : -1);
}

void solve() {
    cin >> line_count >> column_count;
    for (int i = 0; i < line_count; ++i) {
        for (int j = 0; j < column_count; ++j) {
            char ch;
            cin >> ch;

            if (ch == '*')
                matrix[i][j] = -1;
            else if (ch == 'D') {
                matrix[i][j] = 1;
                que.push({i, j});
            }
            else if (ch == 'I')
                init_x = i, init_y = j;
            else if (ch == 'O')
                final_x = i, final_y = j;
        }
    }

    lee_dragons();
    cout << binary_search_solution() << endl;
}

int main() {
    assert(freopen("barbar.in", "r", stdin));
    assert(freopen("barbar.out", "w", stdout));
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    solve();

    return 0;
}