제출 #1352265

#제출 시각아이디문제언어결과실행 시간메모리
1352265gayMaze (JOI23_ho_t3)C++20
94 / 100
1620 ms2162688 KiB
#include <bits/stdc++.h>

using namespace std;

using ld = long double;
using ll = long long;

const int INF = 1e9, MOD = 1e9 + 7;

void solve();

signed main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int q = 1;
    while (q--) {
        solve();
    }
}

vector<pair<int, int>> cord = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

void solve() {
    int r, c, n;
    cin >> r >> c >> n;
    int sr, sc, gr, gc;
    cin >> sr >> sc >> gr >> gc;
    sr--, sc--, gr--, gc--;

    vector<vector<char>> a(r, vector<char>(c));
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            cin >> a[i][j];
        }
    }

    if (r > c) {
        swap(r, c);
        swap(sr, sc);
        swap(gr, gc);
        vector<vector<char>> nw(r, vector<char>(c));
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                nw[i][j] = a[j][i];
            }
        }
        a = nw;
    }

    if (n >= r) {
        queue<pair<int, int>> bfs;
        bfs.emplace(sr, sc);
        vector<vector<int>> used(r, vector<int>(c));
        used[sr][sc] = 1;
        int mn = sc, mx = sc;

        while (!empty(bfs)) {
            auto [i, j] = bfs.front();
            bfs.pop();
            mn = min(mn, j); mx = max(mx, j);
            for (auto [fx, fy] : cord) {
                int x = i + fx, y = j + fy;
                if (x < 0 || y < 0 || x == r || y == c || a[x][y] == '#') {
                    continue;
                }
                if (used[x][y]) {
                    continue;
                }
                used[x][y] = 1;
                bfs.emplace(x, y);
            }
        }

        int col = 0;
        int lf = sc + 1, rf = sc - 1;

        while (!used[gr][gc]) {
            int nwl = max(0, mn - n), nwr = min(c - 1, mx + n);
            for (int i = 0; i < r; i++) {
                for (int j = nwl; j < lf; j++) {
                    used[i][j] = 1;
                }
                for (int j = rf + 1; j <= nwr; j++) {
                    used[i][j] = 1;
                }
            }
            col++;
            lf = nwl;
            rf = nwr;

            for (int i = 0; i < r; i++) {
                bfs.emplace(i, lf);
                bfs.emplace(i, rf);
            }

            while (!empty(bfs)) {
                auto [i, j] = bfs.front();
                bfs.pop();
                mn = min(mn, j); mx = max(mx, j);
                for (auto [fx, fy] : cord) {
                    int x = i + fx, y = j + fy;
                    if (x < 0 || y < 0 || x == r || y == c || a[x][y] == '#') {
                        continue;
                    }
                    if (used[x][y]) {
                        continue;
                    }
                    used[x][y] = 1;
                    bfs.emplace(x, y);
                }
            }
        }
        cout << col << "\n";
        return;
    }

    vector<vector<int>> used(r, vector<int>(c));
    vector<vector<int>> nxt(r, vector<int>(c + 1));
    for (int i = 0; i < r; i++) {
        for (int j = 0; j <= c; j++) {
            nxt[i][j] = j;
        }
    }

    auto get_nxt = [&](auto& self, int i, int j) -> int {
        return nxt[i][j] == j ? j : nxt[i][j] = self(self, i, nxt[i][j]);
    };

    int col = 0;
    queue<pair<int, int>> bfs;
    bfs.emplace(sr, sc);
    used[sr][sc] = 1;
    nxt[sr][sc] = sc + 1;

    vector<pair<int, int>> elems;
    vector<vector<pair<int, int>>> segs(r);

    while (!bfs.empty()) {
        auto [i, j] = bfs.front();
        bfs.pop();
        elems.emplace_back(i, j);
        for (auto [fx, fy] : cord) {
            int x = i + fx, y = j + fy;
            if (x < 0 || y < 0 || x == r || y == c || a[x][y] == '#') {
                continue;
            }
            if (used[x][y]) {
                continue;
            }
            used[x][y] = 1;
            nxt[x][y] = y + 1;
            bfs.emplace(x, y);
        }
    }

    while (!used[gr][gc]) {
        vector<int> id;
        for (auto [x, y] : elems) {
            for (int i = max(0, x - n); i <= min(r - 1, x + n); i++) {
                id.push_back(i);
                int lf = max(0, y - n);
                int rf = min(c - 1, y + n);
                if (abs(x - i) == n) {
                    lf = max(0, y - n + 1);
                    rf = min(c - 1, y + n - 1);
                }
                if (lf <= rf) {
                    segs[i].emplace_back(lf, rf);
                }
            }
        }

        for (auto i : id) {
            if (segs[i].empty()) continue;
            sort(segs[i].begin(), segs[i].end());

            int cur_l = segs[i][0].first;
            int cur_r = segs[i][0].second;

            for (size_t k = 1; k < segs[i].size(); k++) {
                if (segs[i][k].first <= cur_r) {
                    cur_r = max(cur_r, segs[i][k].second);
                } else {
                    int cur = get_nxt(get_nxt, i, cur_l);
                    while (cur <= cur_r) {
                        used[i][cur] = 1;
                        bfs.emplace(i, cur);
                        nxt[i][cur] = cur + 1;
                        cur = get_nxt(get_nxt, i, cur);
                    }
                    cur_l = segs[i][k].first;
                    cur_r = segs[i][k].second;
                }
            }

            int cur = get_nxt(get_nxt, i, cur_l);
            while (cur <= cur_r) {
                used[i][cur] = 1;
                bfs.emplace(i, cur);
                nxt[i][cur] = cur + 1;
                cur = get_nxt(get_nxt, i, cur);
            }
            segs[i].clear();
        }

        vector<pair<int, int>> nw;
        while (!bfs.empty()) {
            auto [i, j] = bfs.front();
            bfs.pop();
            nw.emplace_back(i, j);
            for (auto [fx, fy] : cord) {
                int x = i + fx, y = j + fy;
                if (x < 0 || y < 0 || x == r || y == c || a[x][y] == '#') {
                    continue;
                }
                if (used[x][y]) {
                    continue;
                }
                used[x][y] = 1;
                nxt[x][y] = y + 1;
                bfs.emplace(x, y);
            }
        }
        elems = move(nw);
        col++;
    }
    cout << col << "\n";
}
#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...