需要移动多少步才能到达目的地?高效注水

2024-01-04

我想通过四向移动的次数来计算单元格与目标单元格的距离以到达某处。因此,紧邻目的地的四个单元格的距离为 1,每个单元格的四个基本方向上的单元格的距离为 2,依此类推。最大距离可能约为 16 或 20,并且有些单元格被障碍物占据;距离可以绕过它们,但不能穿过它们。

我想将输出存储到二维数组中,并且我希望能够非常快速地计算更大迷宫地图上任何目的地的“距离图”。

我通过洪水填充的变体成功地做到了这一点,其中我将相邻未填充单元格的增量距离放入优先级队列中(使用 C++ STL)。

我对这个功能很满意,现在想专注于优化代码,因为它对性能非常敏感。

可能会有什么狡猾而快速的方法呢?


我认为你做的一切都是对的。如果您编码正确,则需要O(n)时间和O(n)用于计算洪水填充的内存,其中n是细胞的数量,可以证明不可能做得更好(一般情况下)。填写完成后,您只需返回任何目的地的距离即可O(1),很容易看出它还可以做得更好。

所以如果你想优化性能,你只能关注代码局部优化。这不会影响渐近复杂度,但可以显着提高实际执行时间。但在没有实际查看源代码的情况下,很难给你任何代码优化的建议。

因此,如果您确实想查看优化的代码,请参阅以下内容(纯 C):

#include <stdlib.h>

int* BFS()
{
    int N, M; // Assume we have NxM grid.
    int X, Y; // Start position. X, Y are unit based.
    int i, j;
    int movex[4] = {0, 0, 1, -1}; // Move on x dimension.
    int movey[4] = {1, -1, 0, 0}; // Move on y dimension.
    
    // TO DO: Read N, M, X, Y
    
    // To reduce redundant functions calls and memory reallocation 
    // allocate all needed memory once and use a simple arrays.
    int* map = (int*)malloc((N + 2) * (M + 2) * sizeof(int)); 
    int leadDim = M + 2;
    // Our map. We use one dimension array. map[x][y] = map[leadDim * x + y];
    // If (x,y) is occupied then map[leadDim*x + y] = -1;
    // If (x,y) is not visited map[leadDim*x + y] = -2;

    int* queue = (int*)malloc(N * M * sizeof(int));
    int first = 0, last =1; 
    
    // Fill the boarders to simplify the code and reduce conditions
    for (i = 0; i < N+2; ++i)
    {
        map[i * leadDim + 0] = -1;
        map[i * leadDim + M + 1] = -1;
    }
    
    for (j = 0; j < M+2; ++j)
    {
        map[j] = -1;
        map[(N + 1) * leadDim + j] = -1;
    }
    
    // TO DO: Read the map.
    
    queue[first] = (X+1) * leadDim + Y + 1;
    map[(X+1) * leadDim + Y + 1] = 0;
    
    // Very simple optimized process loop.
    while (first < last) 
    {
        int current = queue[first];
        int step = map[current];
    
        for (i = 0; i < 4; ++i)
        {
            int temp = current + movex[i] * leadDim + movey[i];
            if (map[temp] == -2) // only one condition in internal loop.
            {
                map[temp] = step + 1;
                queue[last++] = temp;
            }
        }
    
        ++first;
    }
    
    free(queue);
    
    return map;
}

该代码可能看起来很棘手。当然,它不是面向对象(OOP)的,但如果您想要真正快速的东西,那就是您所需要的。

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

需要移动多少步才能到达目的地?高效注水 的相关文章

  • 算法 - 如何有效删除列表中的重复元素?

    有一个list L 它包含以下元素任意类型each 如何有效删除此类列表中的所有重复元素 必须保留订单 只需要一个算法 因此不允许导入任何外部库 相关问题 在Python中 从列表中删除重复项以使所有元素都是唯一的最快算法是什么在维持秩序的
  • 基数首先排序最重要的还是最不重要的,哪个更快?

    我一直在研究基数排序实现 到目前为止粘贴在下面的代码 代码是用 Java 编写的 但在 C C 中应该也能正常工作 正如您从实现中看到的 我首先执行最高有效位 即整数的第 31 位 这似乎更快 因为一旦子组完成 就不再需要迭代 例如 打个比
  • 所有可能的骑士在普罗梅拉的棋盘上移动

    是否有可能用马从初始位置 I J 绕过大小为 N N 的棋盘 并且只访问每个方格一次 define A True A I J false active proctype method bit I 4 bit J 3 bit K 1 bit
  • 用于基本要素匹配的最坏情况 NlogN 算法

    查找两个相同大小数组的元素之间的唯一映射 https stackoverflow com questions 4411940 find the unique mapping between elements of two same size
  • StackOverflowError 计算 BigInteger 的阶乘?

    我正在尝试编写一个Java程序来计算大数的阶乘 它似乎BigInteger无法容纳这么大的数量 下面是我编写的 简单的 代码 public static BigInteger getFactorial BigInteger num if n
  • 为什么《破解编码面试》这个例子的时间复杂度是O(k c^k)?

    该问题来自 破解编码面试 第 6 版 问题 V1 11 以下代码打印长度为 k 的所有字符串 其中字符 是按排序顺序排列的 它通过生成所有长度的字符串来做到这一点 k 然后检查每个是否已排序 什么是运行时间 package QVI 11 P
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • 运行时间为 O(n) 且就地排序的排序算法

    有没有运行时间为O n 并且还分类到位 在某些情况下 最好的情况是 O n 但这可能是因为项目集合已经排序 你正在看 O nlogn 一些较好的平均值 话虽如此 排序算法的 Wiki 还是相当不错的 有一个表格比较了流行的算法 说明了它们的
  • 当平方和为N时,如何找到四个变量的所有可能值?

    A 2 B 2 C 2 D 2 N给定一个整数N 打印出整数值的所有可能组合ABCD求解方程 我猜我们可以比暴力做得更好 天真的暴力会是这样的 n 3200724 lim sqrt n 1 for a 0 a lt lim a for b
  • 处理流星中的长服务器端计算

    我正在使用 jimp https www npmjs com package jimp https www npmjs com package jimp 在meteor JS中生成图像服务器端 换句话说 我正在使用递归算法 计算 图像的像素
  • 计算字符串的所有子串中子序列的出现次数

    我想编写一个算法来计算字符串的所有子字符串中字符子序列 不相交 出现的总数 下面是一个例子 字符串 jabcohnnyjohnny 后续 约翰尼 包含子序列的子字符串 jabcohnny jabcohnnyj jabcohnnyjo jab
  • 线段树java实现[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 你知道 二进制 的良好实现吗线段树 http en wikipedia org wiki Segmen
  • 关于Marching Cubes算法的澄清

    关于Marching Cubes 我对其算法和实现有一些疑问 我已经阅读了 Marching Cubes 的 Paul Bourke 优秀文章以及网站上可用的源代码 但是 我在理解以及如何以自己的方式实现算法方面仍然遇到了一些问题 问题如下
  • 自动跟踪算法

    我正在尝试写一个simple跟踪例程来跟踪电影中的某些点 本质上我有一系列 100 帧长的电影 在黑暗背景上显示一些亮点 我每帧有大约 100 150 个点 它们在电影的过程中移动 我想跟踪它们 所以我正在寻找一些有效的 但可能不会过度实施
  • Python Pandas:沿一列比较两个数据帧,并返回另一个数据帧中两个数据帧的行内容

    我正在处理两个 csv 文件并作为数据框 df1 和 df2 导入 df1 有 50000 行 df2 有 150000 行 我想将 df2 的 时间 与 df1 求时间差并返回所有列的值 对应相似的行 保存在df3中 时间同步 例如 35
  • 当给定块大小时反转单链表

    有一个单连接链表 并给出了块大小 例如 如果我的链表是1 gt 2 gt 3 gt 4 gt 5 gt 6 gt 7 gt 8 NULL我的块大小是4然后反转第一个4元素 然后是第二个 4 个元素 问题的输出应该是4 gt 3 gt 2 g
  • 这个函数(for循环)空间复杂度是O(1)还是O(n)?

    public void check 10 for string i list Integer a hashtable get i if a gt 10 hashtable remove i 这是 O 1 还是 O n 我猜测 O n 但不是
  • c# GDI边缘空白检测算法

    我正在寻找解决方案检测边缘空白c 位图 来自 c 托管 GDI 库 图像将是透明的 or white 大多数 400x 图片的尺寸为 8000x8000px 边缘周围有大约 2000px 的空白 找出边缘的最有效方法是什么 x y 高度和宽
  • 颜色逻辑算法

    我们正在构建一个体育应用程序 并希望将团队颜色融入到应用程序的各个部分 现在 每个团队都可以使用几种不同的颜色来表示 我想做的是执行检查以验证两个团队颜色是否在彼此一定的范围内 这样我就不会显示两个相似的颜色 因此 如果团队 1 的主要团队
  • 使用什么算法来确定使系统达到“零”状态所需的最小操作数?

    这是一种更通用的问题 不是特定于语言的 有关要使用的想法和算法的更多信息 系统如下 它登记朋友群体之间的小额贷款 Alice and Bill要去吃午饭 比尔的卡坏了 所以爱丽丝支付了他的餐费 10 美元 第二天Bill and Charl

随机推荐

  • Google“reCaptcha”有时不会显示/渲染

    有时我必须多次重新加载网页 直到呈现 reCaptcha 我和一个朋友在 Firefox 和 Chrome 上进行了测试 但问题是一致的 并且似乎并不取决于所使用的浏览器 我用来显示 reCaptcha 的代码
  • Java归并排序,“合并”步骤应该用队列还是数组来完成?

    这不是家庭作业 我没有钱上学 所以我一边在高速公路收费站轮班工作一边自学 漫长的夜晚 几乎没有顾客 我试图通过以下方式实现一个简单的 合并排序 thinking首先 如果你想进行一些实际的学习 请稍微伸展一下我的大脑 并且then查看我正在
  • Php 数组对动态数组上的服装尺寸 (XXS XS S M L XL XXL) 和数字进行排序

    我有一个类似这样的数组 Array 0 gt XL 1 gt M 2 gt L 3 gt XL 4 gt S 5 gt XXL 但我想对我的数组进行排序 S M L XL XXL 我知道我可以用 usort 来做到这一点 但是 我得到了一些
  • 为什么“with open()”更适合在 Python 中打开文件?

    通常 当有人发布他们的代码时 人们会在旁边添加 你应该使用with open filename as f现在的语法 我同意大多数老式的f open 陈述没有附带 close 我什至回答过一些问题 其中对 隐式关闭 的依赖是他们编程问题的全部
  • Matlab 软件中的“处理”会减慢程序速度

    每当我保存 更改文件夹或有时看似随机的时间时 当前文件夹图块都会显示一个加载图标并显示 正在处理 我总是必须按 取消 否则 Matlab 软件会变慢或冻结 我的编程课上似乎没有其他人对此有问题 我正在使用 MATLAB R2015b 我可以
  • DocumentDb:没有索引的查询

    当从索引中排除所有路径时 为什么我仍然能够对 ID 以外的字段执行成功的查询 排除所有路径 collection IndexingPolicy ExcludedPaths Add new ExcludedPath Path Query SE
  • 如何从 GCM 获取 Canonical ID

    我正在尝试为我的设备获取唯一的 ID 以便我可以从我的服务器获取推送通知 正如所有教程所说 我使用 GMC 注册 GoogleCloudMessaging gcm GoogleCloudMessaging getInstance conte
  • 数组引用绑定与使用模板的数组到指针转换

    由于重载解析不明确 此代码示例无法编译 void g char t 4 void g char t int main char a 123 g a 仔细阅读重载解析规则可以清楚为什么失败 这里没有问题 如果我们正式将其改造为模板版本 tem
  • 使用IntelliJ作为git mergetool总是一启动就退出

    我已经将 IntelliJ 配置为我的 mac 上的 diff 和 mergetool 但是 git 启动它 命令行总是立即返回 而不是等待 diff 完成 这意味着所执行的更改不会反映在磁盘上 我的配置是 mergetool intell
  • 如何在 MigLayout 中获得一个向右对齐的按钮

    我正在使用 Miglayout 向面板添加一个按钮 并尝试我可能做的事情 但我无法让它转到面板的右端 它坚持向左齐平 奇怪的是 该演示在示例中有点简短 它仅在同一面板上的其他按钮的上下文中显示它 我有一个这样的面板 dialog gt co
  • 如何在 Core Graphics / Quartz 2D 中绘制圆角矩形?

    我需要绘制圆角矩形的轮廓 我知道我可以制作直线和圆弧 但也许还有圆角矩形的功能 您可以使用 UIBezierPath bezierPathWithRoundedRect cornerRadius or UIBezierPath bezier
  • unity3d 和 git 子模块可能吗?

    太长了 这将是一篇冗长的文章 但我相信许多 unity3d 开发人员也遇到了和我一样的问题 这个问题需要一个明确 一劳永逸的答案来拯救我们的集体理智 所以在过去的两年多里我一直在使用 git 但我并没有深入研究它 我可以从 bitbucke
  • UISearchBar inputAccessoryView

    The UISearchBar似乎有inputAccessoryView as a readOnly财产 如何使用我自己的 customToolbar 设置它 Edit 正如下面的评论中提到的 这不再是 iOS 6 后的问题 请参阅UISe
  • 流式传输 okhttp 响应正文

    我正在实施一个服务器发送的事件 http www w3schools com html html5 serversentevents asp使用 OkHttp 的库 服务器发送事件的工作原理是与服务器保持开放的 HTTP 连接 在服务器上
  • C++ 迭代具有混合字符长度的 utf-8 字符串

    我需要循环 utf 8 字符串并获取该字符串的每个字符 字符串中可能有不同类型的字符 例如一字节长度的数字 三字节长度的汉字等 我看了这个post https stackoverflow com questions 2852895 c it
  • git reset --soft 并返回到最新的提交

    所以我只是做了一个 git reset soft 来返回到之前的提交 现在 如果我想返回到之前的最新提交该怎么办 即 最新的提交 我尝试执行 git log 但那里列出的提交没有最新的提交 git reset如果您只想返回并查看旧的提交 那
  • 如果使用 Debug dll,服务不会及时响应启动或控制请求

    我试图在我的计算机上部署 Windows 服务 但是当我尝试启动它时出现以下错误 Windows 无法在本地计算机上启动 myService 错误 1053 该服务未及时响应启动或控制请求 经过一番研究后 我发现我正在使用 调试 选项来编译
  • java中将十六进制数字字符串转换为双精度数字

    java中如何将十六进制数字字符串转换为双精度数字 在 matlab 中很简单 gt gt hex2num c0399999a0000000 ans 25 6000 但我也可以在java中做同样的事情吗 我尝试了 parseInt 但这个数
  • 检测 Control.KeyUp 事件上的 Alt 键时出现问题

    我有一个带有 KeyDown 和 KeyUp 事件的控件 如下所示 我遇到的问题是 x 在 KeyDown 中为 TRUE 但在 KeyUp 中始终为 FALSE 我正在尝试检测 Alt 键 正如您可能已经猜到的那样 有什么我不知道的问题吗
  • 需要移动多少步才能到达目的地?高效注水

    我想通过四向移动的次数来计算单元格与目标单元格的距离以到达某处 因此 紧邻目的地的四个单元格的距离为 1 每个单元格的四个基本方向上的单元格的距离为 2 依此类推 最大距离可能约为 16 或 20 并且有些单元格被障碍物占据 距离可以绕过它