【C++、Python】求多个数的最大公约数、最小公倍数+Hankson的趣味题

        分为【基础】与【提高】部分,其中【基础】是求多个数的最大公约数与最小公倍数,【提高】是Hankson问题。(o゚▽゚)o

如果有误的地方麻烦提出来,感激不尽XDDD 


一、题目

        【基础】求N个数的最大公约数(gcd)和最小公倍数(lcm)。 

        【提高】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的个数。请你帮助他编程求解这个问题。

二、解题思路

     【基础】

       输入多个整数,先将gcd与lcm取值为输入的第一个数字,然后依次输入数字与gcd、lcm求最大公约数、最小公倍数。此处可用vector代替数组,非常的方便。ヾ(゚∀゚ゞ)

     【提高】

       这个问题解题的关键就在于判断要求的数x是否是a1,b1的共同因数,判断方法为:gcd(t/a1,a0/a1)==1 and gcd(b1/b0,b1/t)==1 ,这些参数的意思是t为a1的因数,b1的约数,如果不清楚可以在草稿纸上验算试一下。

       此外我们可以知道x肯定不会大于b1而且x肯定能被b1整除,因此可以用判断b1/x 来减少枚举次数。再结合求最大公倍数的函数即可解决。

三、流程图

【基础】

       【提高】

四、代码实现

【基础】

/****

	@Author:Innocence
	@IDE:dev c++
	@OS:win 10
	@Edition:1.0  3/21
			 2.0  3/22
	@Description:求几个数字的最大公约数,最小公倍数 

****/

#include<iostream>
#include<vector>
using namespace std;
//求最大公约数
int divisor (int a,int b)    
{
	int temp;    //定义整型变量
 	if(a<b) {    //通过比较求出两个数中的最大值和最小值
    	temp=a;
    	a=b;
    	b=temp;
    }    //设置中间变量进行两数交换
   	while(b!=0) {    //通过循环求两数的余数,直到余数为0
    	temp=a%b;
    	a=b;    //变量数值交换
    	b=temp;
    }
  	return a;    //返回最大公约数到调用函数处
}
//求最小公倍数
int multiple (int a,int b)    
{
 	int divisor (int a,int b);    //自定义函数返回值类型
    int temp;
  	temp=divisor(a,b);    //再次调用自定义函数,求出最大公约数
  	return  (a*b/temp);    //返回最小公倍数到主调函数处进行输出
}
int main()
{
	int n;
	cout << "请输入数字数:"<<endl;
	cin >> n;
	vector<int> a;    //创建一个vector
	int b;
	int gcd,lcm; 
	for(int i=0;i<n;i++){
		    cout << "请输入数字:"<<endl;
			cin >> b;
			a.insert(a.begin(),b);
		}
	gcd=a[0];    //令gcd为输入的第一个数字
	lcm=a[0];    //令lcm为输入的第一个数字
	for(int i=0;i<n;i++){
		gcd=divisor(gcd,a[i]);    //参数顺序不影响结果
		lcm=multiple(a[i],lcm);    //参数顺序不影响结果
	}
	cout<<"最大公约数:  "<<gcd<<endl;
	cout<<"最小公倍数:  "<<lcm<<endl;
	return 0;
}

【提高】

###    @Author:Innocence
###    @IDE:IDLE (python 3.7 64bit)
###    @OS:win 10
###    @Edition:1.0   3/19
###             2.0   3/2
###             3.0   3/21
###             4.0   3/22
###    @Description:给定最大公约数和最小公倍数求出可能的个数

def gcd(a,b):    #求最大公约数
    if b==0:
        return a
    else:
        return gcd(b,a%b)
def judge(t):   
    if(t%a1!=0):
        return 0
    return gcd(t/a1,a0/a1)==1 and gcd(b1/b0,b1/t)==1    #t和a0、b0约数相同

print('请输入数据组数:')
n=int(input())    #输入n组数据
while n!=0:
    n-=1
    print('请输入数据')
    a0=int(input())    #输入为字符转化成整数
    a1=int(input())
    b0=int(input())
    b1=int(input())
    ans=0
    for x in range (1,b1):    #不可能超过最小公倍数
        if x*x<=b1:
            if b1%x==0:    #判断是否为因数
                ans=ans+judge(x)
                if b1/x!=x:    #利用x能被b1整除减少枚举次数
                    ans=ans+judge(b1/x)
        x+=1
    print('满足条件的x的个数为:')
    print(ans)    #返回满足条件的数字的个数

五、运行结果

【基础】

【提高】

六、经验归纳

        这次主要遇到的困难就是提高部分,一开始想到了求他们共同的因数,但是不知道具体该怎么求,后来在网上了解了数论的部分知识以及参考别人的做法解决了问题。这次我意识到了在写代码的时候动笔算也特别重要,以后要多多动笔才行。(。•́︿•̀。)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值