1. 程式人生 > >Hankson 的趣味題(數論)

Hankson 的趣味題(數論)

題目描述

【問題描述】 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 的個數。請你幫 助他程式設計求解這個問題。 【輸入】 輸入檔名為 son.in。第一行為一個正整數n,表示有n 組輸入資料。接下來的n 行每 行一組輸入資料,為四個正整數a0,a1,b0,b1,每兩個整數之間用一個空格隔開。輸入 資料保證a0 能被a1 整除,b1 能被b0 整除。 【輸出】 輸出檔案 son.out 共n 行。每組輸入資料的輸出結果佔一行,為一個整數。 對於每組資料:若不存在這樣的 x,請輸出0; 若存在這樣的 x,請輸出滿足條件的x 的個數;

題解:

由題得 :

gcd( x , a0)=a1

x*b0/gcd(x,b0)=b1;

這樣不好看 

x=p*a1;   p=x/a1

a0=q*a1;  q=a0/a1

我們猜測 p,q的關係 :gcd(p,q)==1

設 gcd(p,q)=K != 1

p=k*n

q=k*m

所以 x=k*n*a1,a0=k*m*a1

顯然 gcd(x,a0)=K*a1 不成立

可以推廣結論:

gcd(x,y)=k 則有 gcd(x/k,y/k)=1

這樣就很明朗了

列舉b1的因子記數就行了

#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
using namespace std;
int a0,a1,b0,b1;
int cas,ans;
int gcd(int a,int b){
	return a==0?b:gcd(b%a,a); 
}
int main(){
//	freopen("p1072.in","r",stdin);
	scanf("%d",&cas);
	while(cas--){
		scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
		ans=0;int p=a0/a1;int q=b1/b0;
		for(int x=1;x*x<=b1;x++ ){
			if(b1%x==0){
				if(x%a1==0 && gcd(x/a1,p)==1 && gcd(b1/x,q)==1) ans++;
				int y=b1/x;if(y==x) continue;
				if(y%a1==0 && gcd(y/a1,p)==1 && gcd(b1/y,q)==1) ans++;
			}
		}
		printf("%d\n",ans);
	}
	
	
	return 0;
}