1 条题解

  • 0
    @ 2026-10-26 23:48:27

    思路与算法

    整数判别式先判断无实根与有理根;无理根拆出最大平方因子,得到正根号系数与最简有理部分,按唯一格式输出较大根。

    正确性说明

    较大根统一写成-b/(2a)+sqrt(Δ)/(2|a|)。若Δ为平方,用同符号变换的整数分子和正分母约分;否则分离平方部分令剩余根号数无平方因子,再分别约分有理部分及正根号系数,恰得到题目规定的唯一表示。

    复杂度

    每式O(sqrt(Δ)+log M)试因子上界时间、O(log M)数字文本空间,T式串行;Δ<=5M²、M<=1000。

    易错点

    a为负时根号项分母仍用2|a|,不能直接拿公式加号根;有理部分为0要省略,系数1和分母1按规则省略,不输出空格。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    long long gcd1(long long a, long long b) {
        while (b) {
            long long t = a % b;
            a = b;
            b = t;
        }
        return a;
    }
    string frac(long long p, long long q) {
        if (q < 0) {
            p = -p;
            q = -q;
        }
        long long g = gcd1(llabs(p), q);
        p /= g;
        q /= g;
        return to_string(p) + (q == 1 ? "" : "/" + to_string(q));
    }
    int main() {
        int T, M;
        cin >> T >> M;
        while (T--) {
            long long a, b, c;
            cin >> a >> b >> c;
            long long D = b * b - 4 * a * c;
            if (D < 0) {
                cout << "NO\n";
                continue;
            }
            long long root = sqrtl(D);
            while ((root + 1) * (root + 1) <= D)
                root++;
            while (root * root > D)
                root--;
            long long den = 2 * llabs(a), p = -b * (a > 0 ? 1 : -1);
            if (root * root == D) {
                cout << frac(p + root, den) << "\n";
                continue;
            }
            long long u = 1, v = D;
            for (long long z = 2; z * z <= v; z++)
                while (v % (z * z) == 0) {
                    v /= z * z;
                    u *= z;
                }
            string out;
            if (p)
                out = frac(p, den) + "+";
            long long g = gcd1(u, den);
            u /= g;
            long long q = den / g;
            if (u != 1)
                out += to_string(u) + "*";
            out += "sqrt(" + to_string(v) + ")";
            if (q != 1)
                out += "/" + to_string(q);
            cout << out << "\n";
        }
    }
    
    • 1

    【23CSPJ普及组】一元二次方程(uqe)

    信息

    ID
    1938
    时间
    1000ms
    内存
    512MiB
    难度
    普及−
    标签
    递交数
    0
    已通过
    0
    上传者