题目描述
dreamoon初中时最喜欢在上数学课时睡觉了,每次睡觉时,都会被老师罚解很多道整系数一元二次多项式因式分解成两个整系数一元一次多项式相乘的题目,但dreamoon很狡猾,写了一个能解因式分解的程序,故这个惩罚对dreamoon没什么大不了的。
身为dreamoon粉丝的你,也想效法dreamoon(能够写出解因式分解的程序的部份),现在就来测试看看你写的程序是否正确吧〜
身为dreamoon粉丝的你,也想效法dreamoon(能够写出解因式分解的程序的部份),现在就来测试看看你写的程序是否正确吧〜
至于你应该要输出什么,详情请参考标准输出。
输入描述:
输入的第一行有一个正整数 T,代表该笔测试资料含有多少组因式分解问题。
接下来有 T 行,每个询问各占 1 行,包含 3 个整数 a, b, c,代表这个询问要你对 a·x2 + b·x +c 做因式分解。
输出描述:
对于每个因式分解问题,若有多种把a·x2 + b·x +c 分解成两个整系数一元一次多项式相乘,也就是形如(s·x + t) x (u·x + v) 的方式,请找到使得s·101000+ t·10100 + u·1010 + v 最大的一组解,并输出四个整数s, t, u, v 于一行。 若无法因式分解,则输仍然输出三个整数 a, b, c 于一行。
示例1
输入
3 5 1 -4 5 1 4 5 0 0
输出
5 -4 1 1 5 1 4 5 0 1 0
备注:
1 ≤ T ≤ 20 -109 ≤ a,b,c ≤ 109 a ≠ 0
数据里所有的数都是整数
题解:
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll int
#define LL long long
struct P {
ll s, t, u, v;
bool operator < (const P &tt) const {
if(s != tt.s) return s > tt.s;
if(t != tt.t) return t > tt.t;
if(u != tt.u) return u > tt.u;
return v > tt.v;
}
};
ll a, b, c;
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d %d %d", &a, &b, &c);
LL det = 1LL * b * b - 4LL * a * c;
if(det < 0 || (LL)sqrt(det) * (LL)sqrt(det) != det) { printf("%d %d %d\n", a, b, c); continue; }
LL aa = -b + sqrt(det), bb = -b - sqrt(det);
aa /= 2; bb /= 2;
ll gcd1 = __gcd(aa, (LL)a), gcd2 = __gcd(bb, (LL)a);
gcd1 = abs(gcd1); gcd2 = abs(gcd2);
ll ans1 = aa / gcd1, ans2 = a / gcd1;
ll ans3 = bb / gcd2, ans4 = a / gcd2;
if(a < 0) ans1 *= -1, ans2 *= -1;
ll res = abs(a / ans2 / ans4);
vector<P> p;
p.push_back({ans2 * res, -ans1 * res, ans4, -ans3});
p.push_back({-ans2 * res, ans1 * res, -ans4, ans3});
p.push_back({ans4 * res, -ans3 * res, ans2, -ans1});
p.push_back({-ans4 * res, ans3 * res, -ans2, ans1});
sort(p.begin(), p.end());
printf("%d %d %d %d\n", p[0].s, p[0].t, p[0].u, p[0].v);
}
return 0;
}