[問題描述]
輸入二個正整數x0,y0(2≤x0≤100000,2≤y0≤1000000),求出滿足下列條件的p、q的個數。
條件:1、p、q是正整數
2、要求p、q以xo為最大公約數,以yo為最小公倍數。
試求,滿足條件的所有可能的兩個正整數的個數。
[樣例]
輸入:x0=3 y0=60
輸出:4
說明:(不用輸出)此時的 p q 分別為,
3 60
15 12
12 15
60 3
所以,滿足條件的所有可能的兩個正整數的個數共4種。
知識準備:
若p,q
的最大公約數為
x0,則:
p%x0=0,q%x0=0 假設
p1=p/x0q1=q/x0
進行如下推導:
1。如果
p1=q1,
則根據最大公約數的定義,
p1=q1=1,p=q=x0,
根據最小公倍數的定義,
p=q=y0,
則x0=y0=p=q 2.
如果p1!=q1,
根據最大公約數的定義,p1與
q1除了
1以外沒有其他相同的因子,即
p1,q1
互質。3.
根據最小公倍數的定義,
y0=pq/x0,
又p1=p/x0,q1=q/x0,
則可推出如下的等式:
p1q1=y0/x0.
根據以上分析,可以推出以下演算法: 1
。如果y0%x0!=0,
則p,q
不存在。
2。如果
y0=x0,
則存在一組
p,q,
且p=q=x0=y0
3. 在1
~y0/x0
之間查詢滿足
p1q1=y0/x0
且p1,q1
互質的資料對。
參考程式如下:
#include
#include
using namespace std;
long x,y,p,q,i,s;
int hz(long p,long q)//
判斷p,q
互質int main()
}return 0; }
二。對演算法的改進
1.猜想
根據前面的分析:如果
p,q的最大公約數為
x,最小公倍數為
y,則只要查詢滿足乘積為
y/x且互質的
p1,q1
資料對就可以了。這樣的資料對個數有沒有規律呢?
猜想:設
y0/x0
的質因子個數為
k,則滿足條件的
p,q對個數為
2^k,
即集合中子集合的數目。
證明:假設
y0/x0有k
個質因子,
y0/x0=a1*a1*…ak (ai
是質數,算術基本定理)
要使得p1*q1=y0/x0,
且p1,q1
互質,則
p1,q1
不能含有相同的的質因子,因此
p1,q1
的選擇總數為
如何統計整數
s的質因子個數
k?最簡單的方法是線性查詢。從
2開始依次累加,第乙個能整除
s的資料必然為質因子,通過迴圈整除操作排除該質因子後,下乙個能整除
s的資料還是質因子。
演算法如下: 1.
i=2;
2.while (s%i!=0) s++;
3.k++;
4.while (s%i==0)s=s/i;
5.繼續執行語句2。
參考程式如下:
#include
#include
using namespace std;
long x,y,p,q,i,s,j,k;
long total;//儲存2^k
int main()
total=1;
for(j=1;j<=s;j++)
total*=2; //計算2^k
cout<
最大公約數 最小公倍數
求最大公約數最直接的辦法是從兩數中較小數與2之間的所有整數中乙個乙個的找。但這個方法有點浪費。有兩種有名的方法 1.輾轉相除法2.更相減損之術這兩種方法比較有名,而且現在人教版的高中數學中已經介紹了這兩種方法。下面這個是第2個,因為它只需要加減法就可以,效率高。int maxfactor unsig...
最小公倍數 最大公約數
求最小公倍數演算法 最小公倍數 兩整數的乘積 最大公約數 求最大公約數演算法 1 輾轉相除法 有兩整數a和 b a b得餘數c 若c 0,則 b即為兩數的最大公約數 若c 0,則 a b,b c,再回去執行 例如求27和 15的最大公約數過程為 27 15 餘12 15 12餘3 12 3餘0 因此...
最大公約數,最小公倍數
兩個數最大公約數 輾轉相除法 在數學中,輾轉相除法,又稱歐幾里得演算法,是求最大公約數的演算法。兩個整數的最大公約數是能夠同時整除它們的最大的正整數。輾轉相除法基於如下原理 兩個整數的最大公約數等於其中較小的數和兩數的差的最大公約數。例如 用 a,b 來表示a和b的最大公約數。已知a,b,c為正整數...