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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/V5ZSQ/article/details/83110107

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

猜你喜欢

转载自blog.csdn.net/V5ZSQ/article/details/83110107
110
今日推荐