有效的算法来检查二元迷宫是否可以通过限制移动来解决

2023-12-02

我遇到了一个生成二元维度迷宫的问题r x c (0/false对于阻塞的细胞和1/true免费手机)。每个迷宫都应该是可解决的。

一个人可以从(i, j)到任一(i + 1, j)(向下)或(i, j + 1)(正确的)。求解器预计达到(r - 1, c - 1)(最后一个单元格)从(0, 0)(第一个单元格)。

下面是我的算法(修改后的 BFS)来检查迷宫是否可解。它运行在O(r*c)时间复杂度。我正在尝试以更好的时间复杂度找到解决方案。谁能建议我一些其他算法?我不想要路径,我只是想检查一下。

#include <iostream>
#include <queue>
#include <vector>

const int r = 5, c = 5;

bool isSolvable(std::vector<std::vector<bool>> &m) {
    if (m[0][0]) {
        std::queue<std::pair<int, int>> q;
        q.push({0, 0});
        while (!q.empty()) {
            auto p = q.front();
            q.pop();
            if (p.first == r - 1 and p.second == c - 1)
                return true;
            if (p.first + 1 < r and m[p.first + 1][p.second])
                q.push({p.first + 1, p.second});
            if (p.second +1 < c and m[p.first][p.second + 1])
                q.push({p.first, p.second + 1});
        }
    }
    return false;
}

int main() {
    char ch;

    std::vector<std::vector<bool>> maze(r, std::vector<bool>(c));
    for (auto &&row : maze)
        for (auto &&ele : row) {
            std::cin >> ch;
            ele = (ch == '1');
        }

    std::cout << isSolvable(maze) << std::endl;
    return 0;
}

递归解决方案:

bool exploreMaze(std::vector<std::vector<bool>> &m, std::vector<std::vector<bool>> &dp, int x = 0, int y = 0) {
    if (x + 1 > r or y + 1 > c) return false;
    if (not m[x][y]) return false;
    if (x == r - 1 and y == c - 1) return true;
    if (dp[x][y + 1] and exploreMaze(m, dp, x, y + 1)) return true;
    if (dp[x + 1][y] and exploreMaze(m, dp, x + 1, y)) return true;
    return dp[x][y] = false;
}

bool isSolvable(std::vector<std::vector<bool>> &m) {
    std::vector<std::vector<bool>> dp(r + 1, std::vector<bool>(c + 1, true));
    return exploreMaze(m, dp);
}

具体需求:

我的目标是在我的代码中多次使用此函数:更改网格的某个点,然后重新检查是否会更改结果。是否有可能进行记忆,以便可以重复使用运行中生成的结果?这可以给我更好的平均时间复杂度。


如果多次调用此函数且变化较小,则有一种称为 Link-Cut 树的数据结构,它支持 O(log n) 时间内的以下操作:

  1. 链接(链接2个图形节点)
  2. 剪切(从图形中剪切给定边)
  3. 已连接? (检查 2 个节点是否由某些边连接)

考虑到网格是一个隐式图,我们可以首先构建 Link-Cut 树,在O(n*m*log(n*m)) time

然后,所有更新(添加一些节点/删除一些节点)都可以通过删除/添加相邻边来完成,这只会花费O(log(n*m)) time


不过我建议优化迷宫生成算法而不是使用这种复杂的数据结构。使用 DFS 可以很容易地完成迷宫生成

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有效的算法来检查二元迷宫是否可以通过限制移动来解决 的相关文章

  • 使用sqlbulkcopy之前如何创建表

    我有一个 DBF 文件 我正在尝试导入该文件 然后将其写入 SQL 表 我遇到的问题是 如果我使用 SqlBulkCopy 它需要我提前创建表 但在我的场景中这是不可能的 因为 dbf 文件不断变化 到目前为止 这是我的代码 public
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • 在异步请求中使用超时回调

    我之前问过这个问题 但我将用提出的解决方案来完成这个问题 并提出另一个问题 我正在使用这个类来进行异步网络请求 http msdn microsoft com en us library system net webrequest aspx
  • 当 foreach 块的内容具有 Conditional 属性时,C# 编译器是否会对其进行优化?

    我正在工作中编写一些调试代码 我想知道我所做的是否会损害性能 让我们看一下代码 foreach var item in aCollection Debug WriteLine item Name 我知道 Debug 类使用 Conditio
  • 如何在 ASP.NET Core 6.0 Web API 项目中启用 cors?

    在我的 ASP NET Core 6 0 Web API 项目中配置了 CORS 但预检请求收到 http 405 错误 换句话说 不允许使用 HTTP OPTION 看起来 cors 没有启用 我见过的例子config EnableCor
  • 如何从 C# 调用 F# 类型扩展(静态成员函数)

    FSharp 代码的结构如下 我无法控制源代码 namespace FS
  • 应用新设置时如何防止 GraphicsDevice 被丢弃?

    我的游戏窗口允许手动调整大小 这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小 游戏还利用了RenderTarget2D rt2d 在主 Draw 方法中设置主渲染目标 GraphicsDevice SetRenderTarge
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • 如果我重新分配并且新大小为 0,会发生什么情况。这与释放等效吗?

    给出以下代码 int a NULL a calloc 1 sizeof a printf d n a a realloc a 0 printf d n a return 0 它返回 4078904 0 这个 realloc 相当于 free
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 何时分离或加入 boost 线程?

    我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 动态菜单创建IoC

    我想知道是否有人知道我如何创建如何使用 AutoFac 之类的东西来让我动态地允许 dll 创建自己的表单和菜单项以在运行时调用它们 所以如果我有一个 员工 dll 新入门表格 证书表格 供应商 dll 供应商详细信息来自 产品形态 在我的
  • 如何使 WinForms UserControl 填充其容器的大小

    我正在尝试创建一个多布局主屏幕应用程序 我在顶部有一些按钮链接到应用程序的主要部分 例如模型中每个实体的管理窗口 单击这些按钮中的任何一个都会在面板中显示关联的用户控件 面板包含用户控件 而用户控件又包含用户界面 WinForms User
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • 使用方法的状态模式

    我正在尝试使用方法作为状态而不是类来基于状态模式的修改版本来实现一个简单的状态机 如下所示 private Action
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • boost::spirit::qi::语法和可变参数模板

    我在使用可变参数模板定义语法时面临一个问题 我首先定义一些包含在某些结构中的简单语法 例如纬度 经度 如下所示 include
  • 线程安全的有限大小队列,不使用锁

    我正在尝试编写一个主题队列 但遇到死锁和其他多线程问题 我想用Interlocked CompareExchange避免lock用法 但这段代码并没有按预期工作 它只是擦除整个队列 我在这里做错了什么 public class FixedS

随机推荐

  • 合并日期范围

    这里是 Oracle SQL 新手 也是第一次发布海报 我以为这很简单 直到我意识到我无法弄清楚如何拆分返回作业 这是我的分配表 ASGN ID ST DT END DT POS LOCN STATUS WAGE CD A 12 31 20
  • 如何回显公共文件夹之外的图像

    在此项目中 我将管理员提交的文件上传到公共文件夹之外的文件夹 web the public folder upload uploading image to this which is at the same level as the pu
  • 在 ggplot2 中显示频率和条形图

    我正在尝试在条形图中显示频率 好吧 我想要它们某处在图表中 条形下方 条形内 条形上方或图例区域中 我记得 我可能是错的 它可以在ggplot2 这可能是一个简单的问题 至少看起来很容易 这是代码 p lt ggplot mtcars p
  • 使用方法 update_all

    假设我有一个模型 class Result lt ActiveRecord Base attr accessible x y sum end 而不是做 Result all find each do s s sum compute sum
  • 编写一个批处理文件以按日期和时间删除文件夹

    精确重复 如何编写批处理文件来删除文件夹中 5 天或更早的文件 编写一个批处理文件以从文件夹中删除 6 天前的文件 编写一个批处理文件以从文件夹中删除 5 天前的文件 如何编写批处理文件来定期删除文件夹和文件 如何创建按计划删除文件夹的批处
  • 如何在 Web 组件中使用标签的 querySelector

    我正在使用 Web 组件和普通 javascript 构建一个应用程序 我想使用 vaadin router 进行路由 In my 索引 html我只显示Web组件app module
  • 字符在字符串数组中出现的最大次数

    在 C 中 给定数组 string myStrings new string test test test Winner outputs 6 如何找到该字符出现的最大次数 出现在单个字符串中 我当前的解决方案是 int maxOccurre
  • WP7:获取手机名称

    我正在寻找一个简单的信息 我想获取用户当前使用的设备的名称 例如 我想获取 Eric s Phone 就像在 Zune 中一样 是否可以 我寻找设备扩展属性 参见link 或 UserExtendedProperties 参见link 谢谢
  • 具有评分函数和改装参数的 GridSearchCV

    我的问题似乎类似于this one但那里没有可靠的答案 我正在进行多类多标签分类 为此我定义了自己的评分器 然而 为了有refit参数并获得模型的最佳参数 最后我们需要引入一个评分函数来进行改装 如果我这样做 我会收到以下错误missing
  • 如何以成对方式添加两个数组

    我想将两个具有相同长度的 JavaScript 数组的值相加以获得第三个数组 以便第三个数组的第一个值是两个第一个数组的第一个值的总和 第三个数组的第二个值是array 是前两个数组的第二个值的总和 依此类推 例如 var array1 1
  • z-index 不适用于固定定位

    我有一个div使用默认定位 即position static and a div with a fixed位置 如果我设置元素的 z 索引 似乎不可能使固定元素位于静态元素后面 over width 600px z index 10 und
  • Service Fabric 多租户

    我们计划将 Azure Service Fabric 用于面向数据的多租户应用程序 通常有 100 多个客户 每个客户有 5 100 个用户 查看文档 我得出的结论是 最好的方法是为每个客户使用应用程序实例 而不是尝试使用配置文件来实现多租
  • 如何为 JTextPane 内的文本设置删除线和下划线样式选项?

    我有一个 JTextPane 组件 我试图将用户输入的文本样式设置为同时带有下划线和删除线 应该将下一个键入的字符的删除线属性设置为 true 的相关代码片段是这样的 JEditorPane editor getEditor e if ed
  • Windows Phone 7 键盘尺寸

    我想在键盘出现在屏幕上时调整页面大小 我一整天都在寻找任何线索 但什么也没找到 就我而言 我想要完整的页面文本框和它下面的一些按钮
  • 快速绘制多个图表的计时问题

    在下面的代码中 我正在进行一个实验 我需要每秒绘制近 10 个图表 时间间隔 100 总共 50 个图表 但是 当我减少时间间隔时时间间隔 第 120 行向下到底部 从 200 毫秒到 100 毫秒 代码引发下面的异常 我已经厌倦了 inv
  • 无效的日期时间格式:从 Java 将日期/时间插入到 Access 中

    我想向 Access 插入日期时间值 但收到此错误 net ucanaccess jdbc UcanaccessSQLException UCAExc 3 0 4 数据异常 无效的日期时间格式 这是代码 private void txtsu
  • 如何使用正则表达式获取两个管道之间的所有内容

    我有一个字符串说 String s 印度 vs 澳大利亚 在这种情况下 结果应该只是India 第二种情况 String s 澳大利亚 vs 印度 在这种情况下 结果应该只是India 第三种情况 字符串 s 印度 vs 澳大利亚 结果应仅
  • 使用 OData 源从 SSIS 连接到 SharePoint

    我正在尝试使用 OData 源连接到 Microsoft 云上托管的 SharePoint 我正在尝试将项目相关数据从 SharePoint 列表中拉入 sql 表中 并将其处理到数据仓库中 当我手动登录SharePoint时 它已获得读取
  • VB.NET - 读取包含制表符分隔的整数/双精度的文本文件并将它们存储在数组中

    我有一个包含制表符分隔的整数和双精度数的文本文件 例如 5 TAB 0 3 TAB 2 9 TAB 61 TAB 110 8 TAB 1 1 TAB 5 2 TAB 13 TAB 45 1 TAB 0 8 TAB 1 4 TAB 28 TA
  • 有效的算法来检查二元迷宫是否可以通过限制移动来解决

    我遇到了一个生成二元维度迷宫的问题r x c 0 false对于阻塞的细胞和1 true免费手机 每个迷宫都应该是可解决的 一个人可以从 i j 到任一 i 1 j 向下 或 i j 1 正确的 求解器预计达到 r 1 c 1 最后一个单元