Files
python/TangDou/CSP-J/J-2023/uqe.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

2.2 KiB
Raw Blame History

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;
}