【NOIP2009提高組】HK的趣味題
題目背景
NOIP2009提高組試題2。
題目描述
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 的個數。請你幫助他程式設計求解這個問題。
輸入格式
輸入第一行為一個正整數 n,表示有 n 組輸入資料。 接下來的 n 行每行一組輸入資料,為四個正整數 a0,a1,b0,b1,每兩個整數之間用一個空格隔開。輸入資料保證 a0 能被 a1 整除, b1 能被 b0 整除。
輸出格式
輸出共 n 行。每組輸入資料的輸出結果佔一行,為一個整數。 對於每組資料:若不存在這樣的 x ,請輸出 0 ;若存在這樣的 x ,請輸出滿足條件的 x 的個數。 樣例資料 1 輸入
2 41 1 96 288 95 1 37 1776
輸出
6 2
備註
【樣例說明】 第一組輸入資料,x 可以是 9、18、36、72、144、288,共有 6 個。 第二組輸入資料,x 可以是 48、1776,共有 2 個。 【資料範圍】 對於 50% 的資料,保證有 1≤a0,a1,b0,b1≤10000 且 n≤100。 對於 100% 的資料,保證有 1≤a0,a1,b0,b1≤2,000,000,000 且 n≤2000。
解析:
數學推理題。 若 則有 很好理解,因為如果不等與,說明還有公約數,與是最大公約數相悖。 若 則有 由推出以來的結論可得: 我們將兩式放在一起: 容易發現合法的滿足既是的倍數又是的因數,並且滿足以上二式。 解法就很明顯了,在的複雜度內列舉因數,驗證合法性即可。
程式碼:
#include <bits/stdc++.h>
using namespace std;
int n,a0,a1,b0,b1,p,q,ans;
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
p=a0/a1,q=b1/b0,ans=0;
for(int i=1;i*i<=b1;i++)
{
if(b1%i) continue;
if(!(i%a1)&&__gcd(i/a1,p)==1&&__gcd(b1/i,q)==1) ans++;
int j=b1/i;
if(i==j) continue;
if(!(j%a1)&&__gcd(j/a1,p)==1&&__gcd(b1/j,q)==1) ans++;
}
printf("%d\n",ans);
}
return 0;
}