公路 (CSP-J 2023)
给定一元二次方程的参数,输出方程的代数解。这个就是一个比较繁琐的实现题,要考虑判定式正负,是否可化简等各种情况,情况比较多,要拿满分不容易,还好给的测试数据还是比较充分的。
如果有搞不清楚的,可以参考下面程序和其中注释。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,m,a,b,c;
void rational(int &p, int &q) {
if (p == 0) return;
if (q < 0) {
p = -p;
q = -q;
}
int g = __gcd(abs(p), q);
p /= g;
q /= g;
}
void print_rational(int p, int q) {
if (q == 1) {
printf("%d", p);
} else if (p == 0) {
printf("0");
} else {
printf("%d/%d", p, q);
}
}
int main() {
scanf("%d %d", &t, &m);
while (t--) {
scanf("%d %d %d", &a, &b, &c);
if (a < 0) {
a = -a; b = -b; c = -c;
}
int det = b*b - 4*a*c;
if (det < 0) {
printf("NO\n");
continue;
}
if (det == 0) {
int p = -b;
int q = 2*a;
rational(p, q);
print_rational(p, q);
printf("\n");
continue;
}
int sq = sqrt(det);
for (; sq > 1; sq--) {
if (det % (sq*sq) == 0) {
break;
}
}
det /= sq*sq;
// 有理数通分情况
if (det == 1) {
int p = -b + sq;
int q = 2*a;
rational(p, q);
print_rational(p, q);
printf("\n");
continue;
}
// 无理数情况
// q1
if (b != 0) {
int p = -b;
int q = 2*a;
rational(p, q);
print_rational(p, q);
printf("+");
}
// q2*sqrt(det)
int p = sq;
int q = 2*a;
rational(p, q);
if (p > 1) {
printf("%d*", p);
}
if (det > 1) {
printf("sqrt(%d)", det);
}
if (q > 1) {
printf("/%d", q);
}
printf("\n");
continue;
}
return 0;
}