【算法】逃离大迷宫

题目信息

在一个 10^6 x 10^6 的网格中,每个网格上方格的坐标为 (x, y) 。

现在从源方格 source = sx, sy 开始出发,意图赶往目标方格 target = tx, ty 。数组 blocked 是封锁的方格列表,其中每个 blockedi = xi, yi 表示坐标为 (xi, yi) 的方格是禁止通行的。

每次移动,都可以走到网格中在四个方向上相邻的方格,只要该方格 不 在给出的封锁列表 blocked 上。同时,不允许走出网格。

只有在可以通过一系列的移动从源方格 source 到达目标方格 target 时才返回 true。否则,返回 false。

0 <= blocked.length <= 200

题目解析

很容易让人想到用dfs或bfs遍历所有格子,来确定能否到达终点,但此题的数据范围太大,10^6大概率会超时,所以需要另辟蹊径。

题目告诉我们blocked.length在0,200 , 所以说大部分的位置都是空的,可以走的,那什么情况下无法赶往目标方格呢,就是入口或出口被分别包围起来了。

那我们只要证明,入口和出口没有被包围,就可以说明一定可以从源点走到目标点的。

那么怎么确认有没有被包围,就是我们要解决的问题了:

由题目可知,blocked的大小最多只有200个,而大迷宫是个10^6 * 10^6的超大迷宫,所以最大面积只能是它作为一条斜边依赖于两个墙角。

如果你不能理解,代码里的MAX也是可以设置为200 * 200(甚至是1e5),假设了超过blocked的个数一倍的大小。

之后,利用bfs的方式,分别判断入口和出口有没有被包围即可!

代码

cpp 复制代码
class Solution {
public:
    int EDGE = 1e6 , MAX = 1e5;
    int BASE = 131;
    unordered_set<long long> set;
    int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };

    bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& s, vector<int>& t) {
        int n = blocked.size();
        for(auto& p : blocked)
            set.insert(p[0]*BASE+p[1]);
        MAX = n * (n-1) / 2;
        return check(s,t) && check(t,s);
    }

    bool check(vector<int>& a, vector<int>& b){
        unordered_set<long long> vis;
        queue<pair<int,int> > q;
        q.push({a[0],a[1]});

        while(q.size() > 0 && vis.size() <= MAX){
            auto t = q.front();
            q.pop();
            int x = t.first, y = t.second;
            if(x == b[0] && y == b[1]) return true;

            vis.insert(x * BASE + y);
            for(int i = 0;i<4;i++){
                int nx = x + dir[i][0], ny = y + dir[i][1];
                if(nx < 0 || nx >= EDGE || ny < 0 || ny >= EDGE){
                    continue;
                }

                if(set.count(nx * BASE + ny)) continue;
                if(vis.count(nx * BASE + ny)) continue;

                q.push({nx , ny});
                vis.insert(nx * BASE + ny);
                
            }
        }

        return vis.size() > MAX;
    }
};
相关推荐
octopus_c3 小时前
数据结构:堆(Heap)详解
c语言·数据结构·算法
YH55269848 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
遥感知识服务10 小时前
从局部阈值、双极化到暗地表剔除:NASA OPERA DSWx-S1全球动态水体算法拆解
大数据·人工智能·深度学习·神经网络·算法·机器学习
晚风醉蝶10 小时前
1-13-TimSort
算法
ZJU_统一阿萨姆10 小时前
【算子开发】算子融合与Softmax_LayerNorm实现
人工智能·算法·语言模型·硬件架构
叩码以求索12 小时前
浅谈:前序遍历反转法求解N叉树的后序遍历
算法
北风toto14 小时前
中缀、前缀、后缀表达式
算法·软件设计师
听取WA声一片(无恶意)14 小时前
CSP-J/CSP-S 深度优先搜索(DFS)完全讲义
c++·算法·深度优先
码流怪侠14 小时前
2026年8月GitHub热榜深度拆解:Agent Skills席卷开源圈,一个“技能包“收割5万星
算法·程序员·github
hold?fish:palm14 小时前
30 两两交换链表中的节点
数据结构·算法·链表