1. 程式人生 > >Newcoder 110 C.因式分解(水~)

Newcoder 110 C.因式分解(水~)

Description

d r e a m o o n dreamoon

初中時最喜歡在上數學課時睡覺了,每次睡覺時,都會被老師罰解很多道整係數一元二次多項式因式分解成兩個整係數一元一次多項式相乘的題目,但 d r e a m o o
n dreamoon
很狡猾,寫了一個能解因式分解的程式,故這個懲罰對 d r e a m o
o n dreamoon
沒什麼大不了的。

身為 d r e a m o o n dreamoon 粉絲的你,也想效法 d r e a m o o n dreamoon (能夠寫出解因式分解的程式的部份),現在就來測試看看你寫的程式是否正確吧

至於你應該要輸出什麼,詳情請參考標準輸出。

Input

輸入的第一行有一個正整數 T T ,代表該筆測試資料含有多少組因式分解問題。

接下來有 T T 行,每個詢問各佔 1 1 行,包含 3 3 個整數 a , b , c a, b, c ,代表這個詢問要你對 a x 2 + b x + c a·x^2+ b·x +c 做因式分解。

( 1 T 50000 , 1 0 9 a , b , c 1 0 9 , a 0 ) (1\le T\le 50000,-10^9\le a,b,c\le 10^9,a\neq 0)

Output

對於每個因式分解問題,若有多種把 a x 2 + b x + c a·x^2 + b·x +c 分解成兩個整係數一元一次多項式相乘,也就是形如 ( s x + t ) × ( u x + v ) (s·x + t) \times (u·x + v) 的方式,請找到使得 s 1 0 1000 + t 1 0 100 + u 1 0 10 + v s·10^{1000}+ t·10^{100} + u·10^{10} + v 最大的一組解,並輸出四個整數 s , t , u , v s, t, u, v 於一行。

若無法因式分解,則輸仍然輸出三個整數 a , b , c a, b, c 於一行。

Sample Input

3
5 1 -4
5 1 4
5 0 0

Sample Output

5 -4 1 1
5 1 4
5 0 1 0

Solution

首先根據判別式判斷 a x 2 + b x + c ax^2+bx+c 是否有解,如果有解,直接用求根公式
x 1 = b + b 2 4 a c 2 a , x 2 = b b 2 4 a c 2 a x_1=\frac{b+\sqrt{b^2-4ac}}{2a},x_2=\frac{b-\sqrt{b^2-4ac}}{2a}
做分解 a x 2 + b x + c = a ( x + x 1 ) ( x + x 2 ) ax^2+bx+c=a(x+x_1)(x+x_2)

不妨記 x 1 = t s , x 2 = v u x_1=\frac{t}{s},x_2=\frac{v}{u} ,其中 s , u > 0 , g c d ( s , t ) = g c d ( u , v ) = 1 s,u>0,gcd(s,t)=gcd(u,v)=1

顯然若 s u ̸ a su\not|a 則無整數解,否則化為 a s u ( s x + t ) ( u x + v ) \frac{a}{su}(sx+t)(ux+v) ,記 d = a s u d=\frac{a}{su}

s < u s<u s = u , t < v s=u,t<v ,則交換 s , u s,u 以及 t , v t,v ,然後把 s , t s,t 變為原先的 d |d| 倍使得 s , t s,t 儘可能大,若 d d 為負則對 u , v u,v 取負即可

Code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a;
} 
int T,a,b,c;
ll u,v,s,t;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d",&a,&b,&c);
		ll d=1ll*b*b-4ll*a*c,e=0;
		if(d>=0)e=(ll)sqrt