- 题解
一元二次方程
- @ 2025-7-29 13:59:36
参考代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int gcd(int a, int b)
{
if (a % b == 0) return b;
return gcd(b, a%b);
}
void solve()
{
int a, b, c;
cin >> a >> b >> c;
int delta = b*b-4*a*c;
if (delta < 0) cout << "NO\n"; // 无解
else // 有解
{
// delta = 0,x1=x2
if (delta == 0) // -b/2a
{
int p = -b, q = 2*a; // p分子,q分母,答案p/q
// 用最大公约数约分
int gpq = gcd(abs(p), abs(q));
p = p / gpq;
q = q / gpq;
// 保证分母为正
if (q < 0) p=-p,q=-q;
// 特判分母为1
if (q == 1) printf("%d\n", p);
else printf("%d/%d\n",p,q);
}
else // delta > 0, 有两个实数解,输出较大的那个
{
int p = -b, q = 2*a;
// 检查delta 是否完全平方数
int t = sqrt(delta);
if (t * t == delta) // 完全平方数
{
// 令分母为正,保证 [p+sqrt(delta)]/q 为较大解
if (q < 0) p*=-1,q*=-1;
p = p + t; // 加上sqrt(delta)
// 对p/q约分
int gpq = gcd(abs(p),abs(q));
p = p / gpq;
q = q / gpq;
if (q == 1) printf("%d\n", p);
else printf("%d/%d\n",p,q);
}
else // delta 不是完全平方数。a > 0:-b/2a + sqrt(delta)/2a 为较大解
{
// 先处理分式1 --> -b/2a
int gpq = gcd(abs(p), abs(q));
p /= gpq, q /= gpq;
if (q < 0) p*=-1, q*=-1;
if (p!=0) // 分式1存在
{
if (q == 1) printf("%d+",p);
else printf("%d/%d+",p,q);
}
// 处理分式2 --> Δ/2a
q = abs(2*a);
// 化简根式,比如sqrt(12) --> 2sqrt(3) --> dt1 sqrt(dt2);
// 枚举i*i是否为delta的约数
int dt1 = 1, dt2 = delta;
for (int i = sqrt(delta); i >= 1; i--)
{
int divs = i * i;
if (delta % divs == 0)
{
dt2 /= divs;
dt1 = i;
break;
}
}
// 约分dt1 和 q
int gdtq = gcd(abs(dt1), abs(q));
dt1 /= gdtq, q /= gdtq;
if (q < 0) q *= -1, p *= -1;
// 分情况讨论输出
if (q == dt1) // 只有 sqrt(dt2)
printf("sqrt(%d)\n", dt2);
else if (q == 1) // 只有分子dt1*sqrt(dt2)
printf("%d*sqrt(%d)\n", dt1, dt2);
else if (dt1 == 1) // 只有根式部分dt2/q
printf("sqrt(%d)/%d\n",dt2, q);
else // 其它 dt1*sqrt(dt2)/q
printf("%d*sqrt(%d)/%d\n",dt1,dt2,q);
}
}
}
}
int main()
{
// freopen("uqe.in","r",stdin);
// freopen("uqe.out","w",stdout);
int t, m;
cin >> t >> m; // m无用
while (t--)
{
solve();
}
return 0;
}
0 条评论
目前还没有评论...