1 条题解

  • 0
    @ 2025-8-24 22:47:35

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 0x3F
    Wir müssen wissen, wir werden wissen.

    搬运于2025-08-24 22:47:35,当前版本为作者最后更新于2024-06-12 17:23:38,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    注意到,如果我们现在处于 (x,y)(x,y),则我们可以花费 11 单位的代价,到达以 (x,y)(x,y) 为中心的,边长为 2N+12N+1 的正方形区域内的任意一个格子(四个角除外)。若 (x,y)(x,y) 为白格,则还可以不花费任何代价,到达与 (x,y)(x,y) 四连通的格子。

    其中第一种移动方式还可以拆分成一次向四连通格子移动和 N1N-1 次向八连通格子移动。我们可以添加高度维,等价转化为以下模型:

    初始时位于起点,高度为 00

    若当前高度为 00 且位于白格,则可以不花费任何代价,向四连通格移动,高度仍为 00

    若当前高度为 00 且位于黑格,则可以花费 11 单位的代价,向四连通格移动,并且高度变为 N1N-1

    若当前高度不为 00,则可以不花费任何代价,向八连通格移动,高度减少 11

    问需要多少代价到达终点,高度不限。

    我们以代价(从小到大)为第一关键字,高度(从高到低)为第二关键字,跑 01 BFS 即可。

    时间复杂度为 O(rc)\mathcal{O}(rc)

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int dx4[4] = {-1, 0, 0, 1};
    const int dy4[4] = {0, -1, 1, 0};
    const int dx8[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
    const int dy8[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
    const int _ = 6e6 + 10;
    int n, m, k, sx, sy, tx, ty;
    bool arr[_], vis[_];
    inline bool check(int x, int y) {
        return (x >= 1 && x <= n && y >= 1 && y <= m);
    }
    inline int id(int x, int y) {
        return (x - 1) * m + y;
    }
    struct node {
        int x, y, t, h;
    };
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin >> n >> m >> k;
        cin >> sx >> sy;
        cin >> tx >> ty;
        for (int i = 1; i <= n; i++) {
            string str;
            cin >> str;
            for (int j = 1; j <= m; j++) {
                arr[id(i, j)] = (str[j-1] == '#');
            }
        }
        deque<node> Q(1, (node){sx, sy, 0, 0});
        while (true) {
            node N = Q.front();
            Q.pop_front();
            int x = N.x;
            int y = N.y;
            int t = N.t;
            int h = N.h;
            if (vis[id(x, y)]) continue;
            vis[id(x, y)] = true;
            if (x == tx && y == ty) {
                cout << t << endl;
                return 0;
            }
            if (h) {
                for (int d = 0; d <= 7; d++) {
                    int xx = x + dx8[d];
                    int yy = y + dy8[d];
                    if (check(xx, yy) && !vis[id(xx, yy)]) {
                        Q.push_back((node){xx, yy, t, h-1});
                    }
                }
            } else {
                for (int d = 0; d <= 3; d++) {
                    int xx = x + dx4[d];
                    int yy = y + dy4[d];
                    if (check(xx, yy) && !vis[id(xx, yy)]) {
                        if (arr[id(xx, yy)]) {
                            Q.push_back((node){xx, yy, t+1, k-1});
                        } else {
                            Q.push_front((node){xx, yy, t, 0});
                        }
                    }
                }
            }
        }
    }
    
    • 1

    信息

    ID
    8753
    时间
    2000ms
    内存
    2048MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者