有两个变量:a和b。 a的初始值为1,b为0。 有两个按钮:红色和蓝色。红色按钮将b的值添加到a,蓝色按钮将a的值添加到b。
red : a = a+b
blue: b = b+a
现在的问题是,如果在a上可以得到整数X,在b上可以得到Y。
例如,给您X = 7, Y=9.
您从a = 1,b = 0开始。
蓝色按钮两次将使b 0+1+1=2
,而a保持不变。
然后红色按钮可以按下3次,1+2+2+2=7
。
因此,a=7
,b=2
,然后蓝色按钮可以使b 2+7=9
。最后,a=7
和b=9
。
我如何计算使用这两个按钮获得X和Y的可能性?该算法必须适用于较大的数字(> 1000)
您不必知道按钮的路径即可获取数字,而只需了解各种可能性。
答案 0 :(得分:1)
如果(X, Y)
为正,一对X
是可能的,并且X
和Y
的最大公约数为1。这相对容易证明:
首先请注意,如果可以使用
X,Y
,则gcd必须为1。 否则,请考虑gcd不等于的最小X,Y
1.X
和Y
都不能为0。但是最小的X,Y
必须来自可能的X-Y,Y
或X,Y-X
,但是 两者的gcd与X,Y
相同,并且都较小,这与我们的假设相矛盾 极简。第二,假设
X,Y
的gcd等于1(0,1
除外 这是唯一无法与gcd=1
和X=0
配对的货币对。 考虑最小的X,Y
。再说一遍,这一定是来自X-Y,Y
或X,Y-X
都拥有gcd=1
,然后我们又有了一个 极小假设的矛盾。因此,我们证明了
0,1
除外,如果且仅当gcd(X,Y)=1
X,Y
是否可达。
然后可以使用标准的gcd算法来计算答案:
def gcd(a, b):
while b > 0:
a, b = b, a % b
return a
def solvxy(X, Y):
return X>0 and gcd(X, Y)==1
答案 1 :(得分:0)
您可以从X,Y值展开(可能)解。
从较大的值中减去较小的值。
在平局的情况下:对于(1,1),存在解,对于较大的值-不。
如果达到(1,0)值-解决方案确实存在
X Y Sub
7 9 x
7 2 y
5 2 y
3 1 y
1 1 both x and y
for x:
1 0 !!! solution found
递归Python函数:
def solxy(aa, bb):
if (aa < 1):
return False
if (bb == 0):
return (aa == 1)
if (aa == bb):
return (aa == 1)
elif (bb > aa):
return solxy(aa, bb - aa)
else:
return solxy(aa - bb, bb)
print(solxy(7,9))
print(solxy(9,7))
print(solxy(3,3))
print(solxy(3,0))
print(solxy(0,3))
print(solxy(1,0))
True
True
False
False
False
True
修改:
迭代解决方案(使用@squeamish ossifrage提出的模运算):
def solxyit(aa, bb):
while (aa > 1) and (bb > 1):
if (bb > aa):
bb %= aa
else:
aa %= bb
return (aa == 1) or ((bb==1) and (aa>1))
答案 2 :(得分:0)
def two_digits(a, b):
INIT_A = 1
INIT_B = 0
assert ( (type(a) == int or type(a) == long) and (type(b) == int or type(b) == long) )
#print a, b
if a == INIT_A and b == INIT_B:
return True
if a < INIT_A or b < INIT_B:
return False
if a == INIT_A:
times = (b - INIT_B) / INIT_A;
#print times, " press b"
return (times * INIT_A + INIT_B == b)
elif b == INIT_B:
return False #cause a > INIT_A, and INIT_B is 0, thus can't reach(a, INIT_B)
else:
if a > b:
times = (a - INIT_A) / b
return two_digits(a - times * b, b)
elif a < b:
times = (b - INIT_B) / a
return two_digits(a, b - a * times)
else:
return two_digits(0, b) or two_digits(a, 0)
print two_digits(7, 9)
print two_digits(5000, 5003)