机器人可以到达点 (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) 吗? 的相关文章

  • 单词预测算法

    我确信有一篇关于此问题的帖子 但我找不到提出这个确切问题的帖子 考虑以下 我们有字典可供使用 我们收到了许多单词段落 我希望能够根据此输入预测句子中的下一个单词 假设我们有几个句子 例如 你好 我的名字是汤姆 他的名字是杰瑞 他去了没有水的
  • 竞争性编码 - 以最低成本清除所有级别:未通过所有测试用例

    当我遇到这个问题时 我正在一个竞争性编码网站上解决问题 问题指出 游戏中有 N 个关卡和 M 种可用武器 等级编号从 0 到 N 1 武器编号从 0 到 M 1 您可以按任意顺序清除这些级别 在每个关卡中 需要这些 M 武器的某些子集才能通
  • 哪种算法可以有效地找到路径一定距离内的一组点?

    给定一组点s 一组 x y 坐标 和由连接一组点的线段组成的路径l 描述一种有效的算法 可用于从s在指定距离内d路径的l 其实际应用可能是查找沿城市之间的公路旅行路径 10 英里内任意位置的餐馆列表 For example in the f
  • 正则表达式等价

    有没有办法找出两个任意正则表达式是否等价 对我来说看起来很复杂的问题 但可能有一些 DFA 简化机制之类的 要测试等价性 您可以计算的表达式并进行比较
  • 为什么对本地列表求和比用“GHC -O2”对教会编码列表求和慢?

    为了测试教会编码的列表如何针对用户定义的列表和本机列表执行 我准备了 3 个基准测试 用户定义的列表 data List a Cons a List a Nil deriving Show lenumTil n go n Nil where
  • 期望最大化算法的数值示例[重复]

    这个问题在这里已经有答案了 由于我不确定给出的公式 有人可以提供 EM 算法的简单数字示例吗 一个非常简单的具有 4 或 5 个笛卡尔坐标的坐标就可以了 那这个呢 http en wikibooks org wiki Data Mining
  • 如何改进 PHP 分页算法?

    我正在研究 PHP 中的分页算法 我可以猜测它需要改进的空间 所以我想对如何改进它有一些想法 无论是从 UI UX 的角度清理代码本身 还是你能想到的任何其他东西 该算法应输出如下所示的分页 1 2 3 6 7 8 97 98 99 or
  • 给定一个零索引数组 & 该数组的平衡索引[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给出一个由 N 个整数组成的零索引数组 A 该数组的平衡索引是任何整数 P 满足 0 P 例如 考虑以下由 N 8 个元素组成的数组
  • 查找数组中的组合

    我在java中有一个像这样的二维数组 transmission communication tv television approach memorycode methodact 我需要获得所有组合 例如 transmission appr
  • 根据位置计算组合

    我在解决这个问题时遇到了麻烦 创建一个函数 给定字符集 C 可以生成第 N 个组合 或者返回给定起始位置 Ns 和结束位置 Ne 以及组合的最大长度 Mx 的一系列组合 一个具体的例子 令 C A B C 我们知道不同的组合将如下所示 假设
  • 变量的多个值介于 0 和数字序言之间

    所以我一直在尝试自学序言 我认为我进展顺利 然而 我有点坚持我正在尝试的这一种方法 toN N A A 等于 0 到 N 1 之间的整数值 按升序生成 所以 toN 5 A 将是 A 0 A 1 A 2 A 3 A 4 我对序言还很陌生 所
  • 有人真正有效地实现了斐波那契堆吗?

    你们中有人曾经实施过斐波那契堆 http en wikipedia org wiki Fibonacci heap 几年前我就这样做了 但它比使用基于数组的 BinHeaps 慢了几个数量级 当时 我认为这是一个宝贵的教训 告诉我们研究并不
  • 证明字符串算法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 我可以在线性时间内检查有界列表是否包含重复项吗?

    假设我有一个Int列表 其中元素已知是有界的 并且列表已知不长于它们的范围 因此它完全有可能不包含重复项 如何才能最快地测试是否是这种情况 我知道nubOrd https hackage haskell org package contai
  • Haskell:先进先出队列算法的复杂性

    这是我对 FIFO 队列的尝试 type Queue a a gt a empty Queue a empty id remove Int gt Queue a gt a Queue a remove n queue take n queu
  • 全部配对图表上的所有路径

    这可能是一个没有最佳解决方案的问题 假设我有一个有向图 不知道它是否有循环 循环检测将是这个问题的方面之一 给定一组顶点 可能是数百万个顶点 我需要计算给定图的所有唯一对之间的所有不同路径 没有重复顶点的路径 我该如何应对这种情况 让我们看
  • boost::graph 算法是否能够使用以前的解决方案更快地解决密切相关的新问题?

    我在下图中定义了最大流量问题 最初 所有四个边缘的容量均为 4 个单位 我求从 0 到 3 的最大流量值 答案是 8 沿路径 0 gt 1 gt 3 4 个单位 沿路径 0 gt 2 gt 3 4 个单位 以下代码创建图表并查找最大流量 i
  • 动态前缀和

    是否有任何数据结构能够返回数组的前缀和 1 更新元素以及向数组插入 删除元素 所有这些都在 O log n 内 1 前缀和 是从第一个元素到给定索引的所有元素的总和 例如 给定非负整数数组8 1 10 7前三个元素的前缀和是19 8 1 1
  • 如何编写高效的配对算法?

    我需要一种算法的帮助 该算法可以有效地将人们分组 并确保以前的配对不会重复 例如 假设我们有 10 位候选人 candidates 0 1 2 3 4 5 6 7 8 9 并假设我们有一个先前匹配的字典 这样每个键值对即candidate
  • 如何计算某物是否位于某人的视野中

    我有一个对象 它在 2D 空间中具有位置和速度 两者都由向量表示 对象的视野每侧均为 135 度 它看起来与移动的方向相同 速度矢量 我有一些对象 其在 2D 空间中的位置由向量表示 在图中 蓝色背景上的对象是可见的 红色背景上的对象对主体

随机推荐