贴个F的代码

先考虑单纯的最短路,然后考虑限制一个方向且最多可到达一个障碍,求最小值。

#include <bits/stdc++.h>

int main(void) {
    int n, m;
    std::cin >> n >> m;
    bool grid[n][m];
    memset(grid, 0, sizeof(grid));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            char ch;
            std::cin >> ch;
            grid[i][j] = (ch == '.');
        }
    }
    constexpr int INF = 0x3f3f3f3f;
    constexpr int offset[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    int ret1 = [&]() {
        int dis[n][m];
        memset(dis, 0x3f, sizeof(dis));
        using T = std::tuple<int, int, int>; // dis, x, y
        std::priority_queue<T, std::vector<T>, std::greater<>> heap;
        heap.emplace(0, 0, 0);
        while (!heap.empty()) {
            auto [d, x, y] = heap.top();
            heap.pop();
            if (dis[x][y] <= d) {
                continue;
            }
            if (x + 1 == n && y + 1 == m) {
                return d;
            }
            dis[x][y] = d;
            for (int i = 0; i < 4; ++i) {
                int xx = x + offset[i][0], yy = y + offset[i][1];
                if (xx >= 0 && xx < n && yy >= 0 && yy < m && grid[xx][yy] && d + 1 < dis[xx][yy]) {
                    heap.emplace(d + 1, xx, yy);
                }
            }
        }
        return INF;
    }();
    int ret2 = [&]() {
        using ARRAY = std::array<int, 8>;
        int dis[n][m][4][2];
        memset(dis, 0x3f, sizeof(dis));
        using T = std::tuple<int, int, int, int, int>; // dis, x, y, disacrd, selected
        std::priority_queue<T, std::vector<T>, std::greater<>> heap;
        for (int i = 0; i < 4; ++i) {
            heap.emplace(0, 0, 0, i, 0);
        }
        while (!heap.empty()) {
            auto [d, x, y, pos, state] = heap.top();
            heap.pop();
            if (dis[x][y][pos][state] <= d || dis[x][y][pos][state] <= d) {
                continue;
            }
            if (x + 1 == n && y + 1 == m) {
                return d;
            }
            dis[x][y][pos][state] = d;
            for (int i = 0; i < 4; ++i) {
                if (i == pos) {
                    continue;
                }
                int xx = x + offset[i][0], yy = y + offset[i][1];
                if (xx >= 0 && xx < n && yy >= 0 && yy < m) {
                    if (grid[xx][yy]) {
                        if (d + 1 < dis[xx][yy][pos][state]) {
                            heap.emplace(d + 1, xx, yy, pos, state);
                        }
                    } else {
                        if (state == 0 && d + 1 < dis[xx][yy][pos][1]) {
                            heap.emplace(d + 1, xx, yy, pos, 1);
                        }
                    }
                }
            }
        }
        return INF;
    }();
    int ret = std::min(ret1, ret2);
    if (ret == INF) {
        ret = -1;
    }
    std::cout << ret << std::endl;
    return 0;
}

全部评论

相关推荐

点赞 评论 收藏
分享
06-20 21:22
已编辑
门头沟学院 Java
纯真的河老师在喝茶:答应了就跑啊,实习随便跑啊,别被pua了,md就是找个廉价劳动力,还平稳过度正式工,到时候跟你说没转正
点赞 评论 收藏
分享
06-02 15:17
门头沟学院 Java
心爱的idea:怎么会呢 应该是打招呼有问题 问就说实习6个月全国可飞随时到岗
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-04 14:35
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务