分为【基础】与【提高】部分,其中【基础】是求多个数的最大公约数与最小公倍数,【提高】是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) #返回满足条件的数字的个数
五、运行结果
【基础】
【提高】
六、经验归纳
这次主要遇到的困难就是提高部分,一开始想到了求他们共同的因数,但是不知道具体该怎么求,后来在网上了解了数论的部分知识以及参考别人的做法解决了问题。这次我意识到了在写代码的时候动笔算也特别重要,以后要多多动笔才行。(。•́︿•̀。)