1 条题解
-
0
思路与算法
整数判别式先判断无实根与有理根;无理根拆出最大平方因子,得到正根号系数与最简有理部分,按唯一格式输出较大根。
正确性说明
较大根统一写成-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