检查是不是有一种方法可以在任意范围 F 内从 S 点到达 G 点

Posted

技术标签:

【中文标题】检查是不是有一种方法可以在任意范围 F 内从 S 点到达 G 点【英文标题】:Check if there is a Way to get from Point S to Point G in an Arbitrary Range F检查是否有一种方法可以在任意范围 F 内从 S 点到达 G 点 【发布时间】:2021-03-10 18:49:50 【问题描述】:

给定1F 的任意范围以及起点S 和终点G,这样我们唯一可以走的方向是L 左台阶和R 右台阶(也是任意的),创建一个通用解决方案,该解决方案将返回从SR 所需的步数如果可能否则返回not possible

您被绑定到[1, F] 范围内,这意味着如果下一步移动大于F 或小于1,则您不能移动LR 步数

例子:

F = 100
S = 2
G = 1
L = 0
R = 1

Output: not possible

F = 10
S = 1
G = 10
L = 1
R = 2

Output: 6 
Explanation: [1 -> 3(R) -> 5(R) -> 7(R) -> 9(R) -> 8(L) -> 10(R)]

我在课堂上遇到过这个问题,我们当前的主题是二分搜索分而治之。这是我的方法,但这并不能解决一个隐藏的案例。

F = int(input())
S = int(input())
G = int(input())
L = int(input())
R = int(input())
count = 0

while S != G:
    dist = abs(S - G)          # Takes the current distance from S to G
    
    if S > G:
        if S-L > 0:
            S -= L
            count += 1
        else:
            S += R
            count += 1

    else:
        if S+R <= F:
            S += R
            count += 1
        else:
            S -= L
            count += 1

    if dist == abs(S - G):     # If distance doesn't change after trying
        print("not possible")  # a move, conclude that it is not possible.
        break                  

if S == G: print(count)

【问题讨论】:

我投票结束这个问题,因为它没有显示任何努力 怎么样?如果我提出自己的代码不适用于所有情况,它会表现出努力吗?这个问题真的很简单吗? 用我的草稿代码更新了我的帖子。它适用于大多数情况,我不知道我的方法中缺少什么,但我希望这能显示出一些努力。 【参考方案1】:

从数学上讲,这个问题意味着我们正在寻找 以下方程的整数解(x 和 y):

x * R - y * L = G - S

我们可以先创建一个函数来快速检查是否有解决方案:

def path(S, G, F, L, R):
    x=0
    while True:
        y = (x * R - G + S) / L
        if y>=0 and int(y)==y:
            return(x,y)
        else:
            x+=1

如果有解决方案,这将起作用,但如果没有解决方案,则不会。 从数学上可以证明,当 L 除 R 而不是 G-S 时,没有解。证明如下:

如果 R mod L =0(L除R) (G - S)/L != 0(L 不分 G-S)

然后将整个方程 (x * R - y * L = G - S) 除以 L,我们得到:

x * R/L - y = (G - S)/L

y= (x * R/L) - (G - S)/L

现在,对于 x mod 1 =0(x 个整数),我们希望 y mod 1 = 0(意味着 y 是整数)。使用常见的模运算我们采取:

y mod 1 = [(x * R/L) - (G - S)/L] mod 1 =

[(x * R/L) mod 1 - ((G - S)/L) mod 1] mod 1 =

[(x mod 1 * (R/L) mod 1) mod 1 - ((G - S)/L) mod 1] mod 1 =

[(x mod 1 * 0) mod 1 - ((G - S)/L) mod 1] mod 1 =

[((G - S)/L) 模 1] 模 1

如果 L 不除 G-S,则这不能为 0,这最终意味着不存在可以满足原始条件的整数对 x,y。

这对于我们的代码来说,意味着以下添加:

def path(S, G, F, L, R):
        if R%L==0 and (G-S)%L != 0 :
            return 'No solutions'
        x=0
        while True:
            y = (x * R - G + S) / L
            if y>=0 and int(y)==y:
                return(x,y)
            else:
                x+=1

我不知道在数学上我们是否可以证明上面的 if 是唯一的例外,它可能可以通过更多的模运算来证明。以编程方式,我们可以在代码中添加一些时钟,这样如果没有解决方案,这意味着它将进入不定式循环,我们可以在一段时间后返回 False。我们可以这样做:

How would I stop a while loop after n amount of time?

【讨论】:

【参考方案2】:

如果距离没有改变,这并不意味着不可能,您可以跳过该点并以相同的距离到达另一边,想象 L=2,R=1,S=3 , G=2,你从球门的距离 1 开始,向左跳(仍然是距离 1)然后向右跳并获胜。您需要检查的是您是否进入了循环并最终到达了您之前已经尝试过的位置。您可以跟踪这些位置(比如在一组中),或者提前进行一些数学运算,并计算出在您确定循环之前需要多少 Ls 和 Rs(可能不打算弄清楚这一点)。

【讨论】:

【参考方案3】:
F=int(input())
S=int(input())
G=int(input())
L=int(input())
R=int(input())


L*=-1
Fl=1-L
Fr=F-R
h0=set()
n=0
while True:
    if   S<G:
        S+= R if S<=Fr else L
    elif G<S:
        S+= L if Fl<=S else R
    else:
        print(n)
        break
    if S in h0:
        print('not possible')
        break

    h0.add(S)
    n+=1

【讨论】:

以上是关于检查是不是有一种方法可以在任意范围 F 内从 S 点到达 G 点的主要内容,如果未能解决你的问题,请参考以下文章

检查范围是不是重叠

在我的 c++ 程序中有一种方法可以检查 CPU 是不是有 AES-NI

Python:检查范围内是不是存在对象[重复]

如何分组,计算和映射日期范围? [关闭]

针对IF语句测试范围值数组的最佳方法

关于Kubernetes-k8s集群在任意nodes节点上执行kubectl和kubadm命令的方法