机器人可以到达点 (x, y) 吗?

2024-01-25

我在一次求职面试中遇到了这个问题,我无法找到解决方案的正确算法,所以我在这里发布这个问题:

有一个机器人可以通过以下两种方式在坐标平面上移动:

假设机器人当前位置为 (x,y),如果方向如下,则机器人可以移动等于 x 和 y 之和的距离:

(x,y)  ->  (x+y, y)
(x,y)  ->  (x, x+y)

现在给定一个初始点 (x1, y1) 和一个目标点 (x2, y2),您需要编写一个程序来检查机器人是否可以通过任意次数的移动到达目的地。

注:x1、y1、x2、y2 > 0

解释:

  1. 假设机器人的初始点是(2,3),目的地是(7,5)

    这种情况下的结果是肯定的,因为机器人可以采取以下路径:

    (2,3) -> (2, 2+3) => (2, 5)

    (2,5) -> (2+5, 5) => (7,5)

  2. 假设机器人的起始点是(2,3),目的地是(4,5)

    这种情况下的结果为“否”,因为无论机器人采取什么路径,它都无法到达 (4,5)


一种天真的暴力方法

一种方法是递归地探索每一个可能的动作,直到达到目标。

需要考虑的一点是,机器人可以无限期地保持移动(永远不会到达目标),因此您需要一个结束案例才能完成该功能。幸运的是,这个职位一直在增加x and y轴,因此当 x 坐标或 y 坐标大于目标时,您可以放弃探索该路径。

所以像这样:

def can_reach_target(pos, target):
    if pos == target: 
        return True
    if pos[0] > target[0] or pos[1] > target[1]: 
        return False
    return can_reach_target((pos[0], sum(pos)), target) or \
           can_reach_target((sum(pos), pos[1]), target)

它有效:

>>> can_reach_target((2,3),(7,5))
True
>>> can_reach_target((2,3),(4,5))
False

一个限制是这不适用于负坐标 - 不确定这是否是一个要求,只要让我知道是否是,我会调整答案。


回溯

另一方面,如果不允许负坐标,那么我们也可以将其处理为戴夫建议 https://stackoverflow.com/a/52041439/7434365。这更加高效,因为我们认识到机器人到达每个坐标的方式只有一种。

该方法依赖于能够确定我们迈出的方向:增加 x 坐标或 y 坐标。我们可以通过选择两个坐标中较大的一个来确定最后更改的坐标。以下证明保证了情况确实如此。

状态改变的可能性有:

1. (a, b) => (a+b, b)       a x-coordinate change

and,

2. (a, b) => (a, a+b)       a y-coordinate change

在情况 (1) 中,x 坐标现在更大,因为:

    a > 0
a + b > b  (add b to both sides)

同样地,因为b也是> 0,我们可以推断出a+b is > a.


现在我们可以从目标出发问:哪个坐标引导我们来到这里?答案很简单。如果 x 坐标大于 y 坐标,则从 x 坐标中减去 y 坐标,否则从 y 坐标中减去 x 坐标。

也就是说,对于一个坐标,(x,y), if x > y,那么我们来自(x-y,y)否则(x,y-x).


第一个代码现在可以调整为:

def can_reach_target(pos, target):
    if pos == target: 
        return True
    if target[0] < pos[0] or target[1] < pos[1]: 
        return False
    x, y = target
    return can_reach_target(pos, (x-y,y) if x > y  else (x,y-x))

其按预期工作:

>>> can_reach_target((2,3),(7,5))
True
>>> can_reach_target((2,3),(4,5))
False

Timings

>>> timeit.timeit('brute_force((2,3),(62,3))',globals=locals(),number=10**5)
3.41243960801512
>>> timeit.timeit('backtracker((2,3),(62,3))',globals=locals(),number=10**5)
1.4046142909792252
>>> timeit.timeit('brute_force((2,3),(602,3))',globals=locals(),number=10**4)
3.518286211998202
>>> timeit.timeit('backtracker((2,3),(602,3))',globals=locals(),number=10**4)
1.4182081500184722

所以你可以看到回溯器在这两种情况下都快了近三倍。

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

机器人可以到达点 (x, y) 吗? 的相关文章

  • iOS心率检测算法

    我正在尝试在我正在开发的应用程序中实现心跳记录功能 首选方法是使用 iPhone 的摄像头 在灯亮的情况下 让用户将手指放在镜头上 然后检测视频源中与用户心脏相对应的波动 我通过以下堆栈溢出问题找到了一个非常好的起点here https s
  • 查找所有n位相邻数字为1的n位二进制数[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 让我用一个例子来解释一下 如果n 4
  • 如何验证无锁算法?

    从理论上讲 至少应该可以对无锁算法进行暴力验证 只有这么多的函数调用组合 是否有任何工具或正式推理过程可以实际证明无锁算法是正确的 理想情况下它还应该能够检查竞争条件和 ABA 问题 注意 如果你知道一种方法来证明一点 例如 只证明它不受
  • 生成字符串及其子字符串列表的排列的算法

    我已经忘记这个算法有一段时间了 假设我得到了字符串 cccaatt 我试图生成重复字母的每个子串的所有可能变体 EG cccaatt 作为输入将返回 猫 卡特 猫 卡特 ccat 卡特 卡特彼勒 卡特彼勒 cccat cccat cccaa
  • 计算 Adamic-Adar 的快速算法

    我正在研究图形分析 我想计算一个 N N 相似度矩阵 其中包含每两个顶点之间的 Adamic Adar 相似度 为了概述 Adamic Adar 让我从以下介绍开始 给定邻接矩阵A无向图的G CN是两个顶点的所有公共邻居的集合x y 两个顶
  • 什么是确定性快速排序?

    我一直在阅读有关快速排序的内容 发现有时它被称为 确定性快速排序 这是普通快速排序的替代版本吗 普通快速排序和确定性快速排序有什么区别 普通 确定性 快速排序在特定数据集上的行为可能非常差 例如 选择第一个未排序元素的实现在已排序数据上的时
  • 渲染和触摸输入之间的 libgdx 坐标系差异

    我有一个渲染 PNG 图像的屏幕 BaseScreen 实现了 Screen 接口 单击屏幕时 会将角色移动到触摸的位置 用于测试目的 public class DrawingSpriteScreen extends BaseScreen
  • 将整数列表划分为总和相等的 K 个子列表

    类似的问题还有1 https stackoverflow com questions 27322804 partition of a set into k disjoint subsets with equal sum and 2 http
  • 快速排序应用程序中这些交换代码行的目的是什么?

    我试图理解快速排序的实现或应用程序以找到第 k 个最小元素 这是我试图理解的代码 public int quicksort int a int start int end int k if start lt end int pivot pa
  • C#:如何确定坐标是否在美国大陆?

    我正在获取坐标 纬度 经度 我想检查这些坐标是否位于美国大陆 有没有一种简单的方法可以在 C 中实现 我可以将坐标转换为 MGRS 或 UTM 谢谢 哇哦 他们专门为你准备了 http econym org uk gmap states x
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • 如何在单向链表(一次遍历中)中从尾部获取第 n 个节点?

    所以我在一次考试中得到了这个问题 如何从单链表的尾部获取第 n 个节点 每个节点都有一个值和一个下一个 指向下一个值的指针 我们得到这个 getNodeFromTail Node head int x 所以我的做法是通过遍历一次来求出列表的
  • 处理流星中的长服务器端计算

    我正在使用 jimp https www npmjs com package jimp https www npmjs com package jimp 在meteor JS中生成图像服务器端 换句话说 我正在使用递归算法 计算 图像的像素
  • 序列和与 GCD

    大约一个月前 我在编程挑战中遇到了这个问题 但社论尚未发布 所以我在这里问 有一个大小为 N 的数组 A 求 A 的 K 个长度子序列的总和 GCD Example 如果 A 1 2 3 且 K 2 1 2 3 总和 1 GCD 3 1 3
  • 关于Marching Cubes算法的澄清

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

    我正在尝试写一个simple跟踪例程来跟踪电影中的某些点 本质上我有一系列 100 帧长的电影 在黑暗背景上显示一些亮点 我每帧有大约 100 150 个点 它们在电影的过程中移动 我想跟踪它们 所以我正在寻找一些有效的 但可能不会过度实施
  • 是否有一种算法可以在线性时间内计算数组反转?

    我知道有多少倒转 en wikipedia org wiki Inversion 28discrete mathematics 29 in an n 元素数组可以在 O n log n 操作使用增强型归并排序 http www geeksf
  • 当给定块大小时反转单链表

    有一个单连接链表 并给出了块大小 例如 如果我的链表是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
  • 如何在C中实现带连分数的自然对数?

    这里我有一个小问题 根据这个公式创建一些东西 这就是我所拥有的 但它不起作用 弗兰基 我真的不明白它应该如何工作 我尝试用一 些错误的指令对其进行编码 N 是迭代次数和分数部分 我认为它会以某种方式导致递归 但不知道如何 谢谢你的帮助 do
  • 为什么这个算法的Big-O复杂度是O(n^2)?

    我知道这个算法的大O复杂度是O n 2 但我不明白为什么 int sum 0 int i 1 j n n while i lt j sum 即使我们设定了j n n一开始 我们在每次迭代期间递增 i 并递减 j 因此最终的迭代次数不应该比n

随机推荐