You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

P9750 [CSP-J 2023] 一元二次方程

#include <bits/stdc++.h>
using namespace std;

int T, m;
int a, b, c, delta, aa, bb, gcd1, gcd2, q2, r;

// 最大公约数,辗转相除法
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

int main() {
    cin >> T >> m; // 方程数和系数的绝对值上限,这个m后面没有用到

    while (T--) {
        cin >> a >> b >> c; // 方程的a,b,c
        delta = b * b - 4 * a * c;
        aa = 2 * a;
        bb = -1 * b;
        if (a < 0) { // 当a<0时对aa和bb进行处理让a<0和a>0都是统一解
            aa = -1 * aa;
            bb = -1 * bb;
        }

        q2 = 1, r = delta;
        // 对于任意的数求出其q2和r。如果可开平方则r=1
        for (int i = 2; i * i <= r; i++) {
            while (r % (i * i) == 0) { // 如果i*i是r的因子,i可以开方出去
                q2 = q2 * i;           // 记录根号外的系数
                r = r / (i * i);       // r在变小
            }
        }

        if (r == 1) { // 完全平方数
            delta = 0;
            bb = bb + q2;
        }

        gcd1 = gcd(abs(bb), aa);
        gcd2 = gcd(q2, aa);
        if (delta < 0) {
            cout << "NO" << endl;
            continue;
        }
        if (delta == 0) {
            if (bb % aa == 0)
                cout << bb / aa;
            else
                cout << bb / gcd1 << "/" << aa / gcd1;
        } else {           // 即delta>0的场景
            if (bb != 0) { // 前半部分的输出如果bb==0则没有输出
                if (bb % aa == 0)
                    cout << bb / aa;
                else
                    cout << bb / gcd1 << "/" << aa / gcd1;
                cout << "+";
            }
            if (q2 / gcd2 != 1) cout << q2 / gcd2 << "*";
            cout << "sqrt(" << r << ")";
            if (aa / gcd2 != 1) cout << "/" << aa / gcd2; // 处理分母的技巧,==1就不输出
        }
        cout << endl;
    }
    return 0;
}