제출 #1349327

#제출 시각아이디문제언어결과실행 시간메모리
1349327retardeMaze (JOI23_ho_t3)C++20
35 / 100
2095 ms19176 KiB
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int R, C, N;
    cin >> R >> C >> N;

    int sr, sc, gr, gc;
    cin >> sr >> sc;
    cin >> gr >> gc;
    --sr; --sc; --gr; --gc;

    vector<string> a(R);
    for (int i = 0; i < R; i++) cin >> a[i];

    auto inside = [&](int r, int c) {
        return 0 <= r && r < R && 0 <= c && c < C;
    };

    auto id = [&](int r, int c) {
        return r * C + c;
    };

    int V = R * C;
    int S = id(sr, sc);
    int G = id(gr, gc);

    vector<unsigned char> reached(V, 0), inBorder(V, 0);
    vector<int> active = {S};
    reached[S] = 1;

    int ans = 0;

    while (true) {
        if (reached[G]) {
            cout << ans << '\n';
            return 0;
        }

        queue<int> q;
        vector<int> newly;
        newly.reserve(active.size());

        for (int v : active) q.push(v);

        while (!q.empty()) {
            int v = q.front();
            q.pop();

            int r = v / C;
            int c = v % C;

            int dr[4] = {-1, 1, 0, 0};
            int dc[4] = {0, 0, -1, 1};

            for (int k = 0; k < 4; k++) {
                int nr = r + dr[k], nc = c + dc[k];
                if (!inside(nr, nc)) continue;
                int u = id(nr, nc);
                if (reached[u]) continue;
                if (a[nr][nc] != '.') continue;
                reached[u] = 1;
                newly.push_back(u);
                q.push(u);
            }
        }

        for (int v : active) newly.push_back(v);

        if (reached[G]) {
            cout << ans << '\n';
            return 0;
        }

        vector<int> border;
        border.reserve(newly.size() * 2);

        for (int v : newly) {
            int r = v / C;
            int c = v % C;

            int dr[4] = {-1, 1, 0, 0};
            int dc[4] = {0, 0, -1, 1};

            for (int k = 0; k < 4; k++) {
                int nr = r + dr[k], nc = c + dc[k];
                if (!inside(nr, nc)) continue;
                int u = id(nr, nc);
                if (reached[u]) continue;
                if (a[nr][nc] != '#') continue;
                if (inBorder[u]) continue;
                inBorder[u] = 1;
                border.push_back(u);
            }
        }

        if (border.empty()) {
            cout << -1 << '\n';
            return 0;
        }

        vector<int> diff((R + 1) * (C + 1), 0);

        auto add_rect = [&](int r1, int c1, int r2, int c2) {
            if (r1 > r2 || c1 > c2) return;
            diff[r1 * (C + 1) + c1] += 1;
            diff[r1 * (C + 1) + (c2 + 1)] -= 1;
            diff[(r2 + 1) * (C + 1) + c1] -= 1;
            diff[(r2 + 1) * (C + 1) + (c2 + 1)] += 1;
        };

        for (int v : border) {
            int r = v / C;
            int c = v % C;
            int r1 = max(0, r - (N - 1));
            int r2 = min(R - 1, r + (N - 1));
            int c1 = max(0, c - (N - 1));
            int c2 = min(C - 1, c + (N - 1));
            add_rect(r1, c1, r2, c2);
        }

        for (int r = 0; r <= R; r++) {
            for (int c = 1; c <= C; c++) {
                diff[r * (C + 1) + c] += diff[r * (C + 1) + (c - 1)];
            }
        }

        for (int c = 0; c <= C; c++) {
            for (int r = 1; r <= R; r++) {
                diff[r * (C + 1) + c] += diff[(r - 1) * (C + 1) + c];
            }
        }

        vector<int> nextActive;
        nextActive.reserve(border.size());

        for (int r = 0; r < R; r++) {
            for (int c = 0; c < C; c++) {
                if (diff[r * (C + 1) + c] <= 0) continue;
                int v = id(r, c);
                if (reached[v]) continue;
                nextActive.push_back(v);
            }
        }

        for (int v : border) inBorder[v] = 0;

        if (nextActive.empty()) {
            cout << -1 << '\n';
            return 0;
        }

        for (int v : nextActive) reached[v] = 1;

        active.swap(nextActive);
        ans++;
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...