题目要求:
(1).基础题目
求N个数的最大公约数和最小公倍数。用C或C++或java或python语言实现程序解决问题。
要求:
1.程序风格良好(使用自定义注释模板)
2.提供友好的输入输出,并进行输入数据的正确性验证。
(2).提高:
Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1和c2的最大公约数和最小公倍数。现在Hankson认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的x并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的x的个数。请你帮助他编程求解这个问题。
输入格式
输入第一行为一个正整数n,表示有n组输入数据。接下来的n行每行一组输入数据,为四个正整数a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入数据保证a0能被a1整除,b1能被b0整除。
输出格式
输出共n行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的x,请输出0;
若存在这样的x,请输出满足条件的x的个数;
样例输入
2
41 1 96 288
95 1 37 1776
样例输出
6
2
算法设计思路:
(1).基础要求:
对于求n个数的最大公约数与最小公倍数,这次作业使用python来做的;
最大公约数:
首先将输入的n个数据填入列表list中,使用sort()函数将输入的数据排序(升序),记录下列表中最小的数据,记为num,判断num是否能被列表中的所有数据整除,如果可以,则得到的num即是这n个数的最大公约数;否则,将num减一,继续上述的判断。
最小公倍数:
与上面的最大公约数的方法类似,不同之处在于在这里取列表中的最大的数,判断此数是否能整除所有的数,不行的话,将此数每次递增1
(2).提高要求:
输入了四个数:a0,a1,b0,b1
对于一个数x,要满足以下要求:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。
则根据数学推导,x必定满足:a1<=x<=b1
因此只需要在[a1,b1]之间取x,判断是否满足上述两个要求,满足则计数变量count加一
最后输出的count即是所求x的个数
算法流程图:
基本要求:
(1).最大公约数
(2).最小公倍数
提高要求:
源代码
(1).基础要求:
#author: lyq
#time: 2019-3-20
import sys
MAX_INT=sys.maxsize
#求最大公约数
def gcdn(list,n):
list.sort()
max=list[n-1]#排序后的最大值
min=list[0]#排序后的最小值
for t in range(min,0,-1):#从此数向更小的数遍历,每次减一
num=t
count=0#计数变量
for i in range(len(list)):
if list[i] == 0:
num=0
break
elif list[i] % num == 0:
count+=1
else:
break
if count == len(list):
break
return num
#求最小公倍数
def lcmn(list,n):
list.sort()
max=list[n-1]#最大值
for t in range(max,MAX_INT,1):
num=t
count=0
for i in range(len(list)):
if num % list[i] == 0:
count+=1
else:
break
if count == len(list):
return num
list = []
n = int(input("请输入数据规模: "))
for i in range(n):
list.append(int(input("请输入第%d个数: "%(i+1) )))#输入数据
min1=lcmn(list,n)
max1=gcdn(list,n)
print("最大公约数为:%d"% max1)
print("最小公倍数为:%d"% min1)
(2).提高要求:
> #author: lyq
> #time : 2019-3-20
>
> #最大公约数 def gcd(a,b):
> if a < b :
> a,b = b,a
>
> if b == 0:
> return a
>
> else:
> return (gcd(b,a % b))
>
> #最小公倍数 def lcm(a,b):
> return (a * b /gcd(a,b))
>
>
> n=int(input())#输入数据n,代表测试用例数目 for j in range(n):
> a0,a1,b0,b1=map(int,input().split())#输入数据 a0,a1,b0,b1
> i = a1
> count = 0#x的计数变量
> while i>=a1 and i<= b1:#x必定在[a1,b1]之间
> if gcd(i,a0) == a1 and lcm(i,b0) == b1:#得到一个满足条件的x,数目加一
> count += 1
>
> i+=1
>
> print(count)#输出数目
调试及测试:
基础要求:
调试:
输入数据:
求最小公倍数:
求最大公约数:
结果:
测试:
:
提高要求:
输入数据:
求最大公约数
求最小公倍数:
测试截图
总结:
本次作业,是以前一次作业的提升,在求n个数的最大公约数和最小公倍数时,可以采用多种方法,可以是先求两个数的最大公约数,将这个数与剩下的数作为数据,继续前面的过程,直到求到最后两个数的最大公约数,即得到这n个数的最大公约数,
也可以是我此次用的方法,将数据排序后,找到最小的数据,判断它是否能被所有的数整除,能则这个数是最大公约数,否则将其减一,继续判断,也就是说,从输入数中的最小值开始,找到一个最大的能被所有的数整除的数。
在提高要求里,巧妙的运用数学常理,简化步骤,既然x与a0的最大公约数是a1,x与b0的最小公倍数是b1,那么x必定满足:a1<=x<=b1;从这个题来看,数学基础与思想在设计算法时是极为重要的