公路 (CSP-J 2023)

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