Description
dreamoondreamoondreamoon初中时最喜欢在上数学课时睡觉了,每次睡觉时,都会被老师罚解很多道整系数一元二次多项式因式分解成两个整系数一元一次多项式相乘的题目,但dreamoondreamoondreamoon很狡猾,写了一个能解因式分解的程序,故这个惩罚对dreamoondreamoondreamoon没什么大不了的。
身为dreamoondreamoondreamoon粉丝的你,也想效法dreamoondreamoondreamoon(能够写出解因式分解的程序的部份),现在就来测试看看你写的程序是否正确吧
至于你应该要输出什么,详情请参考标准输出。
Input
输入的第一行有一个正整数TTT,代表该笔测试资料含有多少组因式分解问题。
接下来有TTT行,每个询问各占111行,包含333个整数a,b,ca, b, ca,b,c,代表这个询问要你对 a⋅x2+b⋅x+ca·x^2+ b·x +ca⋅x2+b⋅x+c 做因式分解。
(1≤T≤50000,−109≤a,b,c≤109,a≠0)(1\le T\le 50000,-10^9\le a,b,c\le 10^9,a\neq 0)(1≤T≤50000,−109≤a,b,c≤109,a̸=0)
Output
对于每个因式分解问题,若有多种把a⋅x2+b⋅x+ca·x^2 + b·x +ca⋅x2+b⋅x+c 分解成两个整系数一元一次多项式相乘,也就是形如(s⋅x+t)×(u⋅x+v)(s·x + t) \times (u·x + v)(s⋅x+t)×(u⋅x+v) 的方式,请找到使得s⋅101000+t⋅10100+u⋅1010+vs·10^{1000}+ t·10^{100} + u·10^{10} + vs⋅101000+t⋅10100+u⋅1010+v 最大的一组解,并输出四个整数s,t,u,vs, t, u, vs,t,u,v 于一行。
若无法因式分解,则输仍然输出三个整数a,b,ca, b, ca,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
首先根据判别式判断ax2+bx+cax^2+bx+cax2+bx+c是否有解,如果有解,直接用求根公式
x1=b+b2−4ac2a,x2=b−b2−4ac2a
x_1=\frac{b+\sqrt{b^2-4ac}}{2a},x_2=\frac{b-\sqrt{b^2-4ac}}{2a}
x1=2ab+b2−4ac,x2=2ab−b2−4ac
做分解ax2+bx+c=a(x+x1)(x+x2)ax^2+bx+c=a(x+x_1)(x+x_2)ax2+bx+c=a(x+x1)(x+x2)
不妨记x1=ts,x2=vux_1=\frac{t}{s},x_2=\frac{v}{u}x1=st,x2=uv,其中s,u>0,gcd(s,t)=gcd(u,v)=1s,u>0,gcd(s,t)=gcd(u,v)=1s,u>0,gcd(s,t)=gcd(u,v)=1
显然若su̸∣asu\not|asu̸∣a则无整数解,否则化为asu(sx+t)(ux+v)\frac{a}{su}(sx+t)(ux+v)sua(sx+t)(ux+v),记d=asud=\frac{a}{su}d=sua
若s<us<us<u或s=u,t<vs=u,t<vs=u,t<v,则交换s,us,us,u以及t,vt,vt,v,然后把s,ts,ts,t变为原先的∣d∣|d|∣d∣倍使得s,ts,ts,t尽可能大,若ddd为负则对u,vu,vu,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(d);
while(e*e<d)e++;
if(e*e!=d)printf("%d %d %d\n",a,b,c);
else
{
t=b+e,v=b-e,s=u=2*a;
ll g=gcd(abs(s),abs(t));
s/=g,t/=g;
g=gcd(abs(u),abs(v));
u/=g,v/=g;
if(s<0)s=-s,t=-t;
if(u<0)u=-u,v=-v;
if(a%((ll)s*u)!=0)printf("%d %d %d\n",a,b,c);
else
{
a/=s,a/=u;
if(s<u||s==u&&t<v)swap(s,u),swap(t,v);
s*=abs(a),t*=abs(a);
if(a<0)u=-u,v=-v;
printf("%lld %lld %lld %lld\n",s,t,u,v);
}
}
}
return 0;
}