CSU 1871 中南大學網路賽E題 簡單的數論
阿新 • • 發佈:2019-01-24
題目:
Description
擅長數學的小A君不滿足於簡單的求解最大公約數和最小公倍數的問題了,他研究出了一個新的題型準備去考考小B,小A給小B 4個正整數a,b,c,d,他問小B能否找到一個數x,使得a和x的最大公約數為b,c和x的最小公倍數為d。如果有多個這樣的x,將所有的x按由小到大的順序列出來,如果找不到任何一個這樣的x,那麼就輸出-1。
Input
第一行給定一個正整數T,表示有T組資料 (T<=100) 接下來T行每行輸入4個正整數a,b,c,d (這四個數都小於2^31)
Output
對於每組資料按照從小到大的順序輸出所有的x的值,如果一個x都找不到則輸出-1。
Sample Input
1
6 3 5 15
Sample Output
3 15
程式碼:
#include<iostream>
using namespace std;
int gcd(int a, int b)
{
if (b)return gcd(b, a%b);
return a;
}
void f2(int a, int b, int c, int d)
{
if (a%b!=0 || d%c!=0 || d%b!=0)
{
cout << -1;
return;
}
int g = gcd(a / b, d / c), p = d / b;
if (gcd(g,p)>1)
{
cout << -1;
return;
}
a /= b, d /= c;
while (gcd(a, p) > 1)p /= gcd(a, p);
while (gcd(d, p) > 1)b *= gcd(d, p), p /= gcd(d, p);
int i;
for (i = 1; i*i <= p; i++)if (p%i == 0)cout << i*b << " ";
for (; i > 0; i--)if (p%i == 0 && i*i<p)cout << p / i*b << " ";
}
int main()
{
int t, a, b, c, d;
cin >> t;
while (t--)
{
cin >> a >> b >> c >> d;
f2(a, b, c, d);
cout << endl;
}
return 0;
}