练一练「既约分数」
题目描述:
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如
4/3 , 8/1, 1/7,都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?
运行限制
- 最大运行时间:1s
2.最大运行内存:128M
在解决本题之前,我们要先了解一下辗转相除法,这是欧几里得发明的一种简单又富有智慧的方法:
设f(x,y)为x与y的最大公约数,用f表示,则f(x,y)=f(y,x%y)
说明:
1.x%y即为取余,设此值用b表示;
2.且x的值赋给y;
3.b(即取余后)的值赋给x(含递归思想,例2将会说明);
4.至于为什么x和y的最大公约数会等于y和b的最大公约数,只能说这是个规律,证明方法暂不详解,例1后有略解。
例1:
如果我们想求30与12的最大公约数,利用辗转相除法:
30%12=2余6
12%6=2余0
即6为30与12最大公约数。
略解:大体原因就是既然此最大公约数f既然能整除x和y,那就代表x和y除以这个f之后,能让余数消失。余数到哪去了?余数肯定包含在f里面,也就是说,f至少能整除一个b。
例1.1
199%100=1余99
99%1=99余0
其中b为99,f为1,也就是f至少能整除一个b,也就是b除以f绝对无余数!也就是b里至少包含一个的f,此例就包含了99个f!
例2:
如果我们想求12与30的最大公约数,利用辗转相除法:
12%30=0余12
30%12=2余6(递归)
12%6=2余0
即6为12与30最大公约数。
学习了辗转相除法,接下来我们看题:
def gcd(a, b):
temp = 0
while (b > 0):
temp = b
b = a % b
a = temp
return a#只有返回的值是1,才能符合“最大公约数为1“的这个条件
if __name__ == '__main__':
ans=0
for a in range(1, 2021):
for b in range(1, 2021):
if gcd(a,b)==1 :
ans+=1
print( ans)
补:计算最大公约数与最小公倍数
a=4
b=2
def gcd(a,b):
return a if b==0 else gcd(b,a%b)
def lcm(a,b):
return a*b//gcd(a,b)
print(gcd(a,b))#最大公约数
print(lcm(a,b))#最小公倍数