【C++BFS 离散化】1036. 逃离大迷宫|2164
本文涉及知识点
C++BFS算法
LeetCode1036. 逃离大迷宫
在一个 106 x 106 的网格中,每个网格上方格的坐标为 (x, y) 。
现在从源方格 source = [sx, sy] 开始出发,意图赶往目标方格 target = [tx, ty] 。数组 blocked 是封锁的方格列表,其中每个 blocked[i] = [xi, yi] 表示坐标为 (xi, yi) 的方格是禁止通行的。
每次移动,都可以走到网格中在四个方向上相邻的方格,只要该方格 不 在给出的封锁列表 blocked 上。同时,不允许走出网格。
只有在可以通过一系列的移动从源方格 source 到达目标方格 target 时才返回 true。否则,返回 false。
示例 1:
输入:blocked = [[0,1],[1,0]], source = [0,0], target = [0,2]
输出:false
解释:
从源方格无法到达目标方格,因为我们无法在网格中移动。
无法向北或者向东移动是因为方格禁止通行。
无法向南或者向西移动是因为不能走出网格。
示例 2:
输入:blocked = [], source = [0,0], target = [999999,999999]
输出:true
解释:
因为没有方格被封锁,所以一定可以到达目标方格。
提示:
0 <= blocked.length <= 200
blocked[i].length == 2
0 <= xi, yi < 106
source.length == target.length == 2
0 <= sx, sy, tx, ty < 106
source != target
题目数据保证 source 和 target 不在封锁列表内
BFS+离散化
如果有两个或更多的空行挨在一起,只保留一行,其它空行删除。空列也是如此,对结果无影响。
对行列号进行离散化。xs记录左右边界,封锁格的列,起点列,终点列。排序去重。xs[0]编码为0,
如果 xs[i] == xs[i-1]+1,xs[i]编码=xs[i-1]的编码+1;否则xs[i]编码=xs[i-1]的编码+2;
然后BFS。
n = blocked.size 故单格数量:2n × \times × 2n。
BFS的时间复杂度:O(nn)
代码
class CGrid {
public:CGrid(int rCount, int cCount) :m_r(rCount), m_c(cCount) {}template<class Fun1,class Fun2>vector<vector<pair<int, int>>> NeiBo(Fun1 funVilidCur, Fun2 funVilidNext, int iConnect = 4){vector<vector<pair<int, int>>> vNeiBo(m_r * m_c);for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (!funVilidCur(r, c))continue;auto& v = vNeiBo[Mask(r, c)];if ((r > 0)&& funVilidNext(r-1, c)) {v.emplace_back(r-1, c);}if ((c > 0) && funVilidNext(r , c - 1)) {v.emplace_back(r, c - 1);}if ((r+1 < m_r ) && funVilidNext(r + 1, c)) {v.emplace_back(r + 1, c);}if ((c+1 <m_c ) && funVilidNext(r, c + 1)) {v.emplace_back(r, c + 1);}}}return vNeiBo;}vector<vector<int>> Dis( vector<pair<int, int>> start, std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext, const int& iConnect = 4) {static short dir[8][2] = { {0, 1}, {1, 0}, {-1, 0},{ 0, -1},{1,1},{1,-1},{-1,1},{-1,-1} };vector<vector<int>> vDis(m_r, vector<int>(m_c, -1));for (const auto& [r, c] : start) {vDis[r][c] = 0;}for (int i = 0; i < start.size(); i++) {const auto [r, c] = start[i];if (!funVilidCur(r, c)) { continue; }for (int k = 0; k < iConnect; k++) {const int r1 = r + dir[k][0];const int c1 = c + dir[k][1];if ((r1 < 0) || (r1 >= m_r) || (c1 < 0) || (c1 >= m_c)) { continue; }if (funVilidNext(r1, c1) && (-1 == vDis[r1][c1])) {start.emplace_back(r1, c1);vDis[r1][c1] = vDis[r][c] + 1;}}}return vDis;}void EnumGrid(std::function<void(int, int)> call){for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){call(r, c);}}} vector<pair<int, int>> GetPos(std::function<bool(int, int)> fun) {vector<pair<int, int>> ret;for (int r = 0; r < m_r; r++){for (int c = 0; c < m_c; c++){if (fun(r, c)) {ret.emplace_back(r, c);}}}return ret;}inline int Mask(int r, int c) { return m_c * r + c; }const int m_r, m_c;const inline static int s_Moves[][2] = { {1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} };
};class CMyDiscretize //离散化{public:CMyDiscretize(vector<int> nums){sort(nums.begin(), nums.end());nums.erase(std::unique(nums.begin(), nums.end()), nums.end());m_nums = nums;m_mValueToIndex[nums[0]] = 0;int iEmpty = 0;for (int i = 1; i < nums.size(); i++){if (nums[i] - nums[i - 1] > 1) { iEmpty++; }m_mValueToIndex[nums[i]] = i+iEmpty;}}int operator[](const int value)const{auto it = m_mValueToIndex.find(value);if (m_mValueToIndex.end() == it){return -1;}return it->second;}int size()const{return m_mValueToIndex.size();}vector<int> m_nums;protected:unordered_map<int, int> m_mValueToIndex;};class Solution {public:bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) {vector<int > xs = { source[0],target[0],0,99999 }, ys = { source[1],target[1], 0,99999 };for (const auto& v : blocked) {xs.emplace_back(v[0]);ys.emplace_back(v[1]);}CMyDiscretize d1(xs), d2(ys);const int R = d1[d1.m_nums.back()]+1;const int C = d2[d2.m_nums.back()]+1;vector<vector<int>> grid(R, vector<int>(C));for (const auto& v : blocked) {int i1 = d1[v[0]];int i2 = d2[v[1]];grid[i1][i2] = 1;}CGrid eg(R, C);auto Vilid = [&](int r, int c) {return 0 == grid[r][c]; };const auto start = make_pair(d1[source[0]], d2[source[1]]);const int x1 = d1[target[0]];const int y1 = d2[target[1]];auto res = eg.Dis({ start }, Vilid, Vilid);return -1 != res[x1][y1] ;}};
单元测试
vector<vector<int>> blocked;vector<int> source, target;TEST_METHOD(TestMethod1){blocked = { {0,1},{1,0} }, source = { 0,0 }, target = { 0,2 };auto res = Solution().isEscapePossible(blocked, source, target);AssertEx(false, res);}TEST_METHOD(TestMethod2){blocked = {}, source = { 0,0 }, target = { 999999,999999 };auto res = Solution().isEscapePossible(blocked, source, target);AssertEx(true, res);}TEST_METHOD(TestMethod3){blocked = { {100005,100073},{100006,100074},{100007,100075},{100008,100076},{100009,100077},{100010,100078},{100011,100079},{100012,100080},{100013,100081},{100014,100082},{100015,100083},{100016,100084},{100017,100085},{100018,100086},{100019,100087},{100020,100088},{100021,100089},{100022,100090},{100023,100091},{100024,100092},{100025,100091},{100026,100090},{100027,100089},{100028,100088},{100029,100087},{100030,100086},{100031,100085},{100032,100084},{100033,100083},{100034,100082},{100035,100081},{100036,100080},{100037,100079},{100038,100078},{100039,100077},{100040,100076},{100041,100075},{100042,100074},{100043,100073},{100044,100072},{100043,100071},{100042,100070},{100041,100069},{100040,100068},{100039,100067},{100038,100066},{100037,100065},{100036,100064},{100035,100063},{100034,100062},{100033,100061},{100032,100060},{100031,100059},{100030,100058},{100029,100057},{100028,100056},{100027,100055},{100026,100054},{100025,100053},{100024,100052},{100023,100053},{100022,100054},{100021,100055},{100020,100056},{100019,100057},{100018,100058},{100017,100059},{100016,100060},{100015,100061},{100014,100062},{100013,100063},{100012,100064},{100011,100065},{100010,100066},{100009,100067},{100008,100068},{100007,100069},{100006,100070},{100005,100071} };source = {100024,100072}, target = { 999994,999990 };auto res = Solution().isEscapePossible(blocked, source, target);AssertEx(true, res);}
扩展阅读
| 我想对大家说的话 |
|---|
| 工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。 |
| 学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作 |
| 有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注 |
| 闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
| 子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。 |
| 如果程序是一条龙,那算法就是他的是睛 |
| 失败+反思=成功 成功+反思=成功 |
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。
相关文章:
【C++BFS 离散化】1036. 逃离大迷宫|2164
本文涉及知识点 CBFS算法 LeetCode1036. 逃离大迷宫 在一个 106 x 106 的网格中,每个网格上方格的坐标为 (x, y) 。 现在从源方格 source [sx, sy] 开始出发,意图赶往目标方格 target [tx, ty] 。数组 blocked 是封锁的方格列表,其中每个…...
[c语言日寄]在不完全递增序中查找特定要素
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
HtmlRAG:RAG系统中,HTML比纯文本效果更好
HtmlRAG 方法通过使用 HTML 而不是纯文本来增强 RAG 系统中的知识表示能力。通过 HTML 清洗和两步块树修剪方法,在保持关键信息的同时缩短了 HTML 文档的长度。这种方法优于现有基于纯文本的RAG的性能。 方法 其实主要看下围绕html提纯思路,将提纯后的…...
LeetCode题解:2690. 无穷方法对象,Proxy
Problem: 2690. 无穷方法对象 思路 这个问题的核心在于创建一个对象,该对象能够响应对其任何方法的调用,并返回调用的方法名称。为了实现这一点,我们可以利用 JavaScript 中的 Proxy 对象。Proxy 对象允许我们自定义对象的基本操作ÿ…...
在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程
既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…...
2023-arXiv-CoT Prompt 思维链提示提升大型语言模型的推理能力
arXiv | https://arxiv.org/abs/2201.11903 摘要: 我们探讨了如何生成思维链(一系列中间推理步骤)显著提高大型语言模型执行复杂推理的能力。在三个大型语言模型上的实验表明,思维链提示提高了一系列算术、常识和符号推理任务的性…...
程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<10>
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 今天我们继续来复习指针… 目录 一、看一段代码二、 一维数组传参的本质三、冒泡排序3.1 基本思想四、二…...
如何在MacOS上查看edge/chrome的扩展源码
步骤 进入管理扩展页面点击详细信息复制对应id在命令行键入 open ~/Library/Application Support/Microsoft Edge/Default/Extensions/${你刚刚复制的id} 即可打开访达中对应的更目录 注意 由于原生命令行无法直接处理空格 ,所以需要加转义符\,即:open ~/Librar…...
C++病毒(^_^|)(2)
第二期 声明: 仅供损害电脑,不得用于非法。损坏电脑,作者一律不负责。此作为作者原创,转载请经过同意。 直接上代码 #include <bits/stdc.h> #include <windows.h> using namespace std; HHOOK g_hHook;void lrud(…...
CNN|ResNet-50
导入数据 import matplotlib.pyplot as plt # 支持中文 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号import os,PIL,pathlib import numpy as npfrom tensorflow import keras from tensor…...
Java堆外内存的高效利用与性能优化
在Java开发中,堆外内存(Direct Memory)是除Java堆以外的内存区域。它允许Java程序直接分配和管理非堆内存,这为高性能的数据处理提供了可能。 1、 什么是堆外内存? 堆外内存,也称为直接内存(D…...
吉祥汽车泰国首发,用 Unity 实现行业首创全 3D 座舱虚拟世界
11 月 19 日,均瑶集团吉祥智驱(以下简称“吉祥汽车”)首款纯电动汽车 JY AIR 在泰国首发。延续吉祥航空在飞行体验上的优势,吉祥汽车对 JY AIR 赋予了将航空级服务标准延伸至地面的使命,为用户提供一站式大出行体验。此…...
【OpenCV】双目相机计算深度图和点云
双目相机计算深度图的基本原理是通过两台相机从不同角度拍摄同一场景,然后利用视差来计算物体的距离。本文的Python实现示例,使用OpenCV库来处理图像和计算深度图。 1、数据集介绍 Mobile stereo datasets由Pan Guanghan、Sun Tiansheng、Toby Weed和D…...
Uniapp 原生组件层级过高问题及解决方案
文章目录 一、引言🏅二、问题描述📌三、问题原因❓四、解决方案💯4.1 使用 cover-view 和 cover-image4.2 使用 subNVue 子窗体4.3 动态隐藏原生组件4.4 使用 v-if 或 v-show 控制组件显示4.5 使用 position: fixed 布局 五、总结Ἰ…...
iOS实现生物识别
1. info.plist中添加权限申请 <key>NSFaceIDUsageDescription</key> <string>APP would like to use Face ID</string> <key>NSBiometricUsageDescription</key> <string>APP would like to use Touch ID</string>2. 添加库 …...
React 初级教程
一、React 简介 React 是由 Facebook 开发的开源 JavaScript 库,用于构建用户界面(UI)。特点: 声明式编程:通过描述 UI 应该是什么样子(而不是操作 DOM)来构建界面。组件化:将 UI 拆分为独立可复用的组件。跨平台:支持 Web(React)、移动端(React Native)、VR 等。…...
【数据结构初阶第十节】队列(详解+附源码)
好久不见。。。别不开心了,听听喜欢的歌吧 必须有为成功付出代价的决心,然后想办法付出这个代价。云边有个稻草人-CSDN博客 目录 一、概念和结构 二、队列的实现 Queue.h Queue.c test.c Relaxing Time! ————————————《有没…...
萌新学 Python 之列表 list
list 列表:用中括号定义,元素写在中括号之间,元素之间使用逗号分隔 list1 [] # 空列表 list2 [1] # 元素为1个 list3 [a, b, c] print(type(list1), type(list2), type(list3)) # <class list> <class list> <class …...
250213-RHEL8.8-外接SSD固态硬盘
It seems that the exfat-utils package is still unavailable, even after enabling the RPM Fusion repository. This could happen if the repository metadata hasn’t been updated or if the package isn’t directly available in the RPM Fusion repository for RHEL 8…...
游戏引擎学习第99天
仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:制作一些光场(Light Field) 当前的目标是为游戏添加光照系统,并已完成了法线映射(normal maps)的管道,但还没有创建可以供这些正常映射采样的光场。为了继续推进&…...
Linux初始化 配置yum源
问题出现:(报错) 1 切换路径 2 备份需要操作的文件夹 3 更改 CentOS 的 YUM 仓库配置文件,以便使用阿里云的镜像源。 4 清除旧的yum缓存 5 关闭防火墙 6 生成新的yum缓存 7 更新系统软件包 8 安装软件包...
【笛卡尔树】
笛卡尔树 笛卡尔树定义构建性质 习题P6453 [COCI 2008/2009 #4] PERIODNICF1913D Array CollapseP4755 Beautiful Pair[ARC186B] Typical Permutation Descriptor 笛卡尔树 定义 笛卡尔树是一种二叉树,每一个节点由一个键值二元组 ( k , w ) (k,w) (k,w) 构成。要…...
Ubuntu启动geteck/jetlinks实战:Docker启动(无法登录)
参考: JetLinks 物联网基础平台 安装Docker Ubuntu下载安装Docker-Desktop-CSDN博客 sudo apt install -y docker-compose 下载源码 git clone https://github.com/jetlinks/jetlinks-community.git cd jetlinks-community 启动 cd docker/run-all sudo dock…...
Java String 类深度解析:内存模型、常量池与核心机制
目录 一、String初识 1. 字符串字面量的处理流程 (1) 编译阶段 (2) 类加载阶段 (3) 运行时阶段 2. 示例验证 示例 1:字面量直接赋值 示例 2:使用 new 创建字符串 示例 3:显式调用 intern() 注意点1: ⑴. String s1 &q…...
不到一个月,SQLite 3.49.0来了
距离 SQLite 3.48.0 发布不到一个月,SQLite 开发团队于 2025 年 2 月 6 日发布了 SQLite 3.49.0 版本。这更新速度的确让人感动,那么这个版本又有哪些更新呢? 查询优化器 新版本改进了自动索引(query-time index)优化…...
探索顶级汽车软件解决方案:驱动行业变革的关键力量
在本文中,将一同探索当今塑造汽车行业的最具影响力的软件解决方案。从设计到制造,软件正彻底改变车辆的制造与维护方式。让我们深入了解这个充满活力领域中的关键技术。 设计软件:创新车型的孕育摇篮 车辆设计软件对于创造创新型汽车模型至…...
ThreadPoolExecutor 详解
一、ThreadPoolExecutor 核心参数 构造函数如下: public ThreadPoolExecutor(int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 非核心线程空闲存活时间TimeUnit unit, // 存活时间单位BlockingQueue…...
TikTok走红全球:中国短视频平台以全新姿态登陆海外市场
在数字化浪潮中,短视频已经成为全球年轻人表达自我、分享生活的重要方式。TikTok,这个起源于中国的短视频平台,以其独特的魅力和创新的功能在全球范围内迅速走红。本文将探讨TikTok如何以全新姿态登陆海外市场,并分析其成功的关键…...
Qt的QTableWidget样式设置
在 Qt 中,可以通过样式表(QSS)为 QTableWidget 设置各种样式。以下是一些常见的样式设置示例: 1. 基本样式设置 tableWidget->setStyleSheet(// 表格整体样式"QTableWidget {"" background-color: #F0F0F0;…...
计算机毕业设计Python旅游评论情感分析 NLP情感分析 LDA主题分析 bayes分类 旅游爬虫 旅游景点评论爬虫 机器学习 深度学习
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
