1011 最大公约数GCD
输入2个正整数A,B,求A与B的最大公约数。
Input
2个数A,B,中间用空格隔开。(1<= A,B <= 10^9)
Output
输出A与B的最大公约数。
Input示例
30 105
Output示例
15
一道基础题,测试的是数学功底。
这道题用辗转相除法解答,可以用递归函数简单明了地表达出辗转相除这一数学方法。代码如下:
辗转相除法代码
def gcd(a, b):
if b == 0:
return a
return gcd(b, a%b)
while True:
try:
A, B = list(map(int, input().split()))
print(gcd(A,B))
except EOFError:
break
缺点:对与两个整型数较大时,做a%b取模运算的性能会比较低
算法的时间复杂度为O(long(min(a,b)))
更相减损法代码
def gcd(a, b):
if a == b:
return a
if a < b:
return gcd(b-a, a)
else:
return gcd(a-b, a)
while True:
try:
A, B = list(map(int, input().split()))
print(gcd(A,B))
except EOFError:
break
缺点:更相减损法是不稳定的算法,当两个数相差悬殊时,递归次数会非常大。
算法的时间复杂度为O(max(a,b))
辗转相除法与更相减损法结合
其思路如下:
当a和b均为偶数时, gcd(a,b) = 2*gcd(a/2, b/2) = 2*gcd(a>>1, b>>1)
当a为偶数,b为奇数时,gcd(a,b) = gcd(a/2, b) = gcd(a>>1,b)
当a为奇数,b为偶数时,gcd(a,b) = gcd(a, b/2) = gcd(a, b>>1)
当a和b均为奇数时,利用更相减损法运算一次,gcd(a,b) = gcd(b-a, a),此时a-b必然为偶数,又可以继续进行位移运算。
代码如下:
def gcd(a, b):
if a == b:
return a
if a > b:
a, b = b, a
if not a&1 and not b&1:
return gcd(a>>1, b>>1)<<1
elif not a&1 and b&1:
return gcd(a>>1, b)
elif a&1 and not b&1:
return gcd(a, b>>1)
else:
return gcd(b-a, a)
while True:
try:
A,B = list(map(int, input().split()))
print(gcd(A, B))
except EOFError:
break
不但避免了取模运算,而且算法性能稳定,此算法的时间复杂度为O(log(max(a,b)))