最大公约数与最小公倍数的提高训练

题目要求:
(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;从这个题来看,数学基础与思想在设计算法时是极为重要的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值