这段代码实现了一个一元二次方程求解器,能够根据判别式的不同情况,输出格式化的较大解:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
全局变量声明
变量 含义 T 测试用例数量 m 题目中的参数(但代码中未使用) a,b,c 方程 ax2+bx+c=0ax^2+bx+c=0ax2+bx+c=0 的系数 d 判别式 Δ=b2−4ac\Delta = b^2-4acΔ=b2−4ac(化简后根号内的数) k Δ\sqrt{\Delta}Δ 化简后的系数,即 Δ=kd\sqrt{\Delta} = k\sqrt{d}Δ =kd t 临时变量,用于存储最大公约数
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GCD 函数:求最大公约数
* 三元运算符:b ? A : B 表示"如果 b 非零则 A,否则 B"
* 递归实现:欧几里得算法,求 a 和 b 的最大公约数
* 等价写法:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MAIN() 函数:核心逻辑
步骤 1:读取系数并标准化
为什么这样做?
* 方程 ax2+bx+c=0ax^2+bx+c=0ax2+bx+c=0 两边同乘 -1,解不变
* 保证 a > 0,后续计算 2a 作为分母时为正,简化符号处理
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
步骤 2:计算判别式并判断无解
* Δ<0\Delta < 0Δ<0 时无实数解,直接输出 NO
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
步骤 3:化简 Δ\SQRT{\DELTA}Δ
核心技巧:提取所有平方因子
示例 过程 结果 12\sqrt{12}12 12=22×312 = 2^2 \times 312=22×3 → k=2,d=3k=2, d=3k=2,d=3 232\sqrt{3}23 18\sqrt{18}18 18=32×218 = 3^2 \times 218=32×2 → k=3,d=2k=3, d=2k=3,d=2 323\sqrt{2}32 7\sqrt{7}7 无平方因子 → k=1,d=7k=1, d=7k=1,d=7 7\sqrt{7}7
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
步骤 4:有理数解(Δ\DELTAΔ 是完全平方数)
数学原理:
* d=0d=0d=0:Δ=0\sqrt{\Delta}=0Δ =0,解为 x=−b2ax = \frac{-b}{2a}x=2a−b
* d=1d=1d=1:Δ=k\sqrt{\Delta}=kΔ =k(整数),解为 x=−b+k2ax = \frac{-b+k}{2a}x=2a−b+k
输出格式:
* 分子分母约分后,如果分母为 1 则只输出分子
* 否则输出 分子/分母
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
步骤 5:无理数解(Δ\DELTAΔ 不是完全平方数)
数学原理:
x=−b+Δ2a=−b2a⏟q1+k2a⏟q2dx = \frac{-b + \sqrt{\Delta}}{2a} = \underbrace{\frac{-b}{2a}}_{q_1} + \underbrace{\frac{k}{2a}}_{q_2}\sqrt{d} x=2a−b+Δ =q1 2a−b +q2 2ak d
代码逻辑:
1. 输出 q1q_1q1 部分(如果不为 0)
* 约分:gcd(-b, 2a)
* 如果分子为 0,用 goto g 跳过,避免输出 0+...
2. 输出 + 连接符
3. 输出 q2dq_2\sqrt{d}q2 d 部分
* 约分:gcd(k, 2a)
* 如果系数为 1,省略 1*
* 如果分母为 1,省略 /1
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5 个"细节"详解
细节 代码位置 作用 细节1 if(a<0) a=-a,b=-b,c=-c 保证分母 2a > 0,简化符号处理 细节2 abs(gcd(...)) gcd 可能返回负数,取绝对值保证约分正确 细节3 if(2*a/t!=1) 分母为 1 时不输出 /1,符合数学书写习惯 细节4 if(-b/t==0) goto g 避免输出 0+sqrt(...),直接输出 sqrt(...) 细节5 if(k/t!=1) 系数为 1 时不输出 1*,如 sqrt(2) 而非 1*sqrt(2)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MAIN() 函数:输入输出框架
文件重定向:
* 提交 OJ 时,程序会自动从 uqe.in 读输入,向 uqe.out 写输出
* 本地调试时可注释掉这两行,用控制台输入输出
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
样例执行演示
样例:X2−3X+2=0X^2 - 3X + 2 = 0X2−3X+2=0(A=1, B=-3, C=2)
1. d = (-3)² - 4×1×2 = 9 - 8 = 1
2. d == 1 → 有理数解
3. 分子:-b + k*d = 3 + 1×1 = 4
4. 分母:2a = 2
5. 约分:gcd(4, 2) = 2 → 4/2 = 2, 2/2 = 1
6. 输出:2 ✓
样例:X2−2=0X^2 - 2 = 0X2−2=0(A=1, B=0, C=-2)
1. d = 0² - 4×1×(-2) = 8
2. 化简:8 = 2² × 2 → k=2, d=2
3. d != 0,1 → 无理数解
4. q1=−02=0q_1 = \frac{-0}{2} = 0q1 =2−0 =0(跳过输出)
5. q2=22=1q_2 = \frac{2}{2} = 1q2 =22 =1(系数为 1,省略)
6. 输出:sqrt(2) ✓
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------