1. 程式人生 > >CSU 1871 中南大學網路賽E題 簡單的數論

CSU 1871 中南大學網路賽E題 簡單的數論

題目:

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; }