分爲【基礎】與【提高】部分,其中【基礎】是求多個數的最大公約數與最小公倍數,【提高】是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) #返回滿足條件的數字的個數
五、運行結果
【基礎】
【提高】
六、經驗歸納
這次主要遇到的困難就是提高部分,一開始想到了求他們共同的因數,但是不知道具體該怎麼求,後來在網上了解了數論的部分知識以及參考別人的做法解決了問題。這次我意識到了在寫代碼的時候動筆算也特別重要,以後要多多動筆纔行。(。•́︿•̀。)