鉴于任意范围1
来F
和起点S
与终点G
,使得我们可以去的唯一方向是L
左步骤和R
正确流程(也任意),创建一个将返回的步数,将采取从去一个通用的解决方案S
到R
如果有可能,否则返回not possible
。
你受该范围的约束,[1, F]
这意味着如果下一个动作大于或小于一个,则你将无法移动L
或R
移动F
1
例子:
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)
从数学上讲,此问题意味着我们正在寻找以下方程的整数解(对于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而不是GS时,没有解。这是证明:
如果R mod L = 0(L代表R)(G-S)/ L!= 0(L不代表GS)
然后通过将整个方程式(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)mod 1] mod 1
如果L不代表GS,则该值不能为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。这是我们可以做到的: