题目标题:求一元二次方程的根 题目作者:陈建海 浙江大学
本题目要求一元二次方程ax2+bx+c=0的根,结果保留2位小数。
输入格式:
输入在一行中给出3个浮点系数a、b、c,中间用空格分开。
输出格式:
根据系数情况,输出不同结果:
1)如果方程有两个不相等的实数根,则每行输出一个根,先大后小;
2)如果方程有两个不相等复数根,则每行按照格式“实部+虚部i”输出一个根,先输出虚部为正的,后输出虚部为负的;
3)如果方程只有一个根,则直接输出此根;
4)如果系数都为0,则输出"Zero Equation";
5)如果a和b为0,c不为0,则输出"Not An Equation"。
输入样例1:
2.1 8.9 3.5
输出样例1:
-0.44
-3.80
输入样例2:
1 2 3
输出样例2:
-1.00+1.41i
-1.00-1.41i
输入样例3:
0 2 4
输出样例3:
-2.00
输入样例4:
0 0 0
输出样例4:
Zero Equation
输入样例5:
0 0 1
输出样例5:
Not An Equation
这道题目还是有一点难度的,想要拿到全部的采分点必须很细心的考虑到所有的可能。特别是采分点6,是这道题目的一个大坑。后面我们会解释怎样避过这个坑。
思路:就是按照题目要求的分类,对于每一种分类,我们要自己能分析出此时a,b,c所满足的条件
(一)如果方程有两个不相等的实数根,则需满足 a != 0 && b*b-4*a*c > 0
(二)如果方程有两个不相等的复数根,则需满足 a != 0 && b*b-4*a*c < 0
(三)如果方程只有一个根,则需满足 a = 0 && b != 0;
注意:当 a != 0 && b*b-4*a*c == 0,从严格的数学上讲,此时方程有两个相等的实数根,而不是只有一个根,但是出题的老师显然把这种情况算作只有一个根的情况了。
(四)如果系数都为0,即a == 0 && b == 0 && c == 0,此时方程有无数多个根,叫做zero equation,也没有问题。
(五)如果a和b为0,c不为0,即 a == 0 && b == 0 && c != 0,此时方程没有根,输出"Not An Equation"。
注意:因为我们使用浮点数计算(float和double都可以),重点是(1)如果一个浮点数a满足a < 0 && a >-0.005,那么按照%.2f输出a时,得到的是-0.00;(2)当给a赋值 a=-0.0后,a==0为真,但是按照%.2f输出a时,得到的是-0.00;因此为了避免输出实数是出现-0.00的情况,我们需要对 -0.005 < a && a <= 0 的情况单独处理。这就是采分点6的坑。下面上代码
#include <stdio.h>
#include <math.h> // 用到sqrt函数,需要包含math.h文件
int main () {
float a,b,c,r1,r2,c1,c2,t;
scanf("%f%f%f", &a,&b,&c);
if (a < 0) {
a = -a;
b = -b;
c = -c;
} // 方便讨论,先把二次项的系数变为正数
if (a > 0 && b*b-4*a*c > 0) { //两个不相等的实根的情况:
t = sqrt(b*b-4*a*c);
r1 = (-b+t)/(2*a);
r2 = (-b-t)/(2*a);
printf("%.2f\n%.2f", r1, r2); // 对应第采分点0
}
else if (a > 0 && b*b-4*a*c < 0) { //两个不相等的复数根的情况:
t = sqrt(-b*b+4*a*c);
c1 = -b/(2*a);
c2 = t/(2*a);
// 为了避免输出的实部为-0.00,需要分下面两种情况
if (c1 <= -0.005 || c1 > 0) {
printf("%.2f+%.2fi\n",c1,c2); //对应采分点1
printf("%.2f-%.2fi",c1,c2);
}
else if (-0.005 < c1 && c1 <= 0) {
printf("0.00+%.2fi\n",c2); //对应采分点6
printf("0.00-%.2fi",c2);
}
}
else if (a == 0 && b != 0) { // 二次项系数为0,退化为一次方程,只要b不等于0,就一定有一个根
// 为了避免出现-0.00的情况,需要分下面两种情况
if (-0.005 < c/b && c/b <0) printf("0.00"); // 并没有对应的采分点,可以自己用 0 4 0.001 测试
else printf("%.2f", -c/b); //对应采分点2
}
else if (a > 0 && b*b-4*a*c == 0) { // 严格从数学上讲,这种情况并不是只有一个根,而是有两个相同的根
printf("%.2f", -b/(2*a)); // 对应采分点5
}
else if (a == 0 && b == 0 && c == 0) { // 系数全为零,有无穷多个根
printf("Zero Equation"); // 对应采分点3
}
else if (a == 0 && b == 0 && c != 0) { // 没有根
printf("Not An Equation"); // 对应采分点4
}
return 0;
}