제출 #1349320

#제출 시각아이디문제언어결과실행 시간메모리
1349320retardeMaze (JOI23_ho_t3)C++20
35 / 100
2095 ms63104 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 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);
    vector<int> active = {S};

    vector<int> vis1(V, 0), vis2(V, 0), borderMark(V, 0), seedMark(V, 0);
    int t1 = 1, t2 = 1, tb = 1, ts = 1;

    vector<int> borderCells;
    vector<int> component;
    vector<int> seeds;
    vector<int> nextActive;

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

    auto pref_at = [&](int r, int c) -> int& {
        return pref[r * (C + 1) + c];
    };

    int ans = 0;

    while (true) {
        deque<int> q;
        component.clear();

        ++t1;
        for (int x : active) {
            if (vis1[x] == t1) continue;
            vis1[x] = t1;
            q.push_back(x);
        }

        while (!q.empty()) {
            int v = q.front();
            q.pop_front();
            component.push_back(v);

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

            if (r > 0) {
                int u = v - C;
                if (vis1[u] != t1 && (a[r - 1][c] == '.' || reached[u])) {
                    vis1[u] = t1;
                    q.push_back(u);
                }
            }
            if (r + 1 < R) {
                int u = v + C;
                if (vis1[u] != t1 && (a[r + 1][c] == '.' || reached[u])) {
                    vis1[u] = t1;
                    q.push_back(u);
                }
            }
            if (c > 0) {
                int u = v - 1;
                if (vis1[u] != t1 && (a[r][c - 1] == '.' || reached[u])) {
                    vis1[u] = t1;
                    q.push_back(u);
                }
            }
            if (c + 1 < C) {
                int u = v + 1;
                if (vis1[u] != t1 && (a[r][c + 1] == '.' || reached[u])) {
                    vis1[u] = t1;
                    q.push_back(u);
                }
            }
        }

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

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

        ++tb;
        borderCells.clear();

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

            if (r > 0) {
                int u = v - C;
                if (vis1[u] != t1 && a[r - 1][c] == '#' && borderMark[u] != tb) {
                    borderMark[u] = tb;
                    borderCells.push_back(u);
                }
            }
            if (r + 1 < R) {
                int u = v + C;
                if (vis1[u] != t1 && a[r + 1][c] == '#' && borderMark[u] != tb) {
                    borderMark[u] = tb;
                    borderCells.push_back(u);
                }
            }
            if (c > 0) {
                int u = v - 1;
                if (vis1[u] != t1 && a[r][c - 1] == '#' && borderMark[u] != tb) {
                    borderMark[u] = tb;
                    borderCells.push_back(u);
                }
            }
            if (c + 1 < C) {
                int u = v + 1;
                if (vis1[u] != t1 && a[r][c + 1] == '#' && borderMark[u] != tb) {
                    borderMark[u] = tb;
                    borderCells.push_back(u);
                }
            }
        }

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

        fill(pref.begin(), pref.end(), 0);
        for (int v : borderCells) {
            int r = v / C;
            int c = v % C;
            pref_at(r + 1, c + 1) = 1;
        }

        for (int r = 1; r <= R; r++) {
            int rowBase = r * (C + 1);
            int prevBase = (r - 1) * (C + 1);
            for (int c = 1; c <= C; c++) {
                pref[rowBase + c] += pref[rowBase + c - 1] + pref[prevBase + c] - pref[prevBase + c - 1];
            }
        }

        ++ts;
        seeds.clear();

        for (int r = 0; r < R; r++) {
            int r1 = max(0, r - (N - 1));
            int r2 = min(R - 1, r + (N - 1));
            for (int c = 0; c < C; c++) {
                int c1 = max(0, c - (N - 1));
                int c2 = min(C - 1, c + (N - 1));

                int sum = pref_at(r2 + 1, c2 + 1) - pref_at(r1, c2 + 1) - pref_at(r2 + 1, c1) + pref_at(r1, c1);
                if (sum > 0) {
                    int v = id(r, c);
                    seedMark[v] = ts;
                    seeds.push_back(v);
                }
            }
        }

        ++t2;
        deque<int> q2;
        nextActive.clear();

        for (int v : seeds) {
            if (vis2[v] == t2) continue;
            vis2[v] = t2;
            q2.push_back(v);
        }

        while (!q2.empty()) {
            int v = q2.front();
            q2.pop_front();

            if (!reached[v]) nextActive.push_back(v);

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

            if (r > 0) {
                int u = v - C;
                if (vis2[u] != t2 && a[r - 1][c] == '.') {
                    vis2[u] = t2;
                    q2.push_back(u);
                }
            }
            if (r + 1 < R) {
                int u = v + C;
                if (vis2[u] != t2 && a[r + 1][c] == '.') {
                    vis2[u] = t2;
                    q2.push_back(u);
                }
            }
            if (c > 0) {
                int u = v - 1;
                if (vis2[u] != t2 && a[r][c - 1] == '.') {
                    vis2[u] = t2;
                    q2.push_back(u);
                }
            }
            if (c + 1 < C) {
                int u = v + 1;
                if (vis2[u] != t2 && a[r][c + 1] == '.') {
                    vis2[u] = t2;
                    q2.push_back(u);
                }
            }
        }

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

        active.swap(nextActive);
        ans++;
    }

    return 0;
}
#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...