洛谷:P9750
OJ:P4980
gcd()
用于计算两个数的最大公因数,并将结果输出成最简分数的形式。它主要用于输出解的有理数部分。gcd2()
用于判断一个数是否为平方数;gcd1()
则用于判断该数是否含有平方因子。这两个函数帮助处理当解含有无理数的情况。a
, b
, c
,并将方程标准化(系数变为正)。代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | #include <iostream> #include <vector> #include <cmath> using namespace std; // 计算两个数 d 和 e 的最大公因数,并将其化简成最简形式 void gcd(int d, int e) { int f, i = 2; f = min(abs(d), e); // 获取 d 和 e 中的较小值 while (i <= f) { if (d % i == 0 && e % i == 0) { d = d / i; // 化简分子 e = e / i; // 化简分母 } else { i++; } } // 输出化简后的结果 if (e == 1) { cout << d; // 如果分母为 1,输出整数 } else { cout << d << '/' << e; // 否则输出分数 } } // 判断 d 是否可以被某个平方数整除,即判断是否存在 n > 1 使 d % (n^2) == 0 bool gcd1(int d) { int n = 0; for (int i = 2; i * i < d; i++) { if ((d % (i * i)) == 0) n = i; } return n != 0; // 如果存在这样的数,则返回 true } // 判断 d 是否为某个整数的平方 bool gcd2(int d) { for (int i = 1; i < d; i++) { if (d == i * i) return true; } return false; } int main() { int n, m; // n 表示方程数量,m 表示系数绝对值的上限 int f, g, h; cin >> n >> m; // 输入方程数量和系数上限 vector<int> a(n + 1, 0); vector<int> b(n + 1, 0); vector<int> c(n + 1, 0); // 输入每个方程的系数 a, b, c,并将系数转化为非负处理 for (int i = 1; i <= n; i++) { cin >> f >> g >> h; if (f > 0) { a[i] = f; b[i] = g; c[i] = h; } else { a[i] = -f; b[i] = -g; c[i] = -h; } } int delt; // 定义 delta 变量用于判断解的情况 for (int i = 1; i <= n; i++) { delt = b[i] * b[i] - 4 * a[i] * c[i]; // 计算 discriminant Δ = b^2 - 4ac // 如果 Δ == 0 且 b == 0,表示方程的解是 0 if (delt == 0 && b[i] == 0) { cout << 0 << '\n'; continue; } // 如果 Δ < 0,无实数解 if (delt < 0) cout << "NO"; // 如果 Δ == 0,且有实数解 if (delt == 0) { if (b[i] == 0) cout << 0; // 特殊情况,直接输出 0 else gcd(-b[i], 2 * a[i]); // 否则,输出化简后的解 } // 如果 Δ == 1,则解为有理数,按分数形式输出 if (delt == 1) { if ((-b[i] + 1) == 0) cout << 0; else gcd(-b[i] + 1, 2 * a[i]); } // 如果 Δ > 0 且不等于 1 if (delt > 0 && delt != 1) { // 如果 Δ 不是平方数,先输出有理部分再输出无理数部分 if ((b[i] != 0) && (!gcd2(delt))) { gcd(-b[i], 2 * a[i]); cout << '+'; } // 如果 Δ 是平方数,直接输出解 if (gcd2(delt)) { if ((-b[i] + sqrt(delt)) == 0) cout << 0; else gcd(-b[i] + sqrt(delt), 2 * a[i]); } // 处理 Δ 为非平方数的情况 else if (gcd1(delt)) { int n = 0; for (int i = 2; i * i < delt; i++) { if (delt % (i * i) == 0) n = i; } int m = n; int e = 2 * a[i]; int f = min(m, e); int i = 2; // 对 sqrt 部分进行化简 while (i <= f) { if (m % i == 0 && e % i == 0) { m = m / i; e = e / i; } else { i++; } } // 输出化简后的无理数部分 if (e == 1) { if (m != 1) cout << m << '*' << "sqrt(" << delt / (n * n) << ")"; else cout << "sqrt(" << delt / (n * n) << ")"; } else { if (m != 1) cout << m << '*' << "sqrt(" << delt / (n * n) << ")/" << e; else cout << "sqrt(" << delt / (n * n) << ")/" << e; } } // 处理无理数部分 else { cout << "sqrt(" << (b[i] * b[i] - 4 * a[i] * c[i]) << ")/" << 2 * a[i]; } } cout << '\n'; } } |