【算法】逃离大迷宫

题目信息

在一个 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;
    }
};
相关推荐
huohaiyu27 分钟前
深入解析Java垃圾回收机制
java·开发语言·算法·gc
浮芷.34 分钟前
鸿蒙PC端 TTS 并发调用问题详解:资源竞争与队列管理
算法·华为·开源·harmonyos·鸿蒙·鸿蒙系统
装不满的克莱因瓶42 分钟前
掌握感知器的学习原理
人工智能·python·神经网络·算法·ai·卷积神经网络
Lsk_Smion43 分钟前
力扣实训 _ [994].腐烂的橘子/图论
算法·leetcode·图论
轻微的风格艾丝凡1 小时前
两电平三相VSC整流模式从不控整流平滑切换至有源整流调试记录
算法·dsp·c2000
dongf20191 小时前
R语言KNN算法
算法·数据分析·r语言
小O的算法实验室1 小时前
2025年IEEE TASE,基于双层耦合平均场博弈的大规模智能体集成任务分配与轨迹规划
人工智能·算法·机器学习
8Qi82 小时前
LeetCode 337:打家劫舍 III(House Robber III)—— 题解 ✅
算法·leetcode·二叉树·动态规划
地平线开发者2 小时前
从 INT64 Div 算子约束到 Cast 修复全流程
算法
AI科技星2 小时前
基于奇合数边界的离散解析数论与双螺旋宇宙本体大统一体系论文全部数学公式汇总表
人工智能·算法·机器学习·架构·学习方法