Problem C: 求一元二次方程的根
Time Limit: 1 Sec Memory Limit: 2 MB
Submit: 6375 Solved: 986
[Submit][Status][Web Board]
Description
一元二次方程的标准形式为ax2+bx+c=0(a≠0),其中a、b、c为常数。求解一元二次方程的根x时有三种情况,分别为(记Δ=b2-4ac):
1. Δ>0,有两个不等的实根;
2. Δ=0,有两个相同的实根;
3. Δ<0,有两个共轭的虚根。
Input
输入为多行,每行为一元二次方程的三个常数a,b,c,在double类型范围之内。当输入的a为0时,表示输入结束。
Output
每行输入的样例对应三行输出。
第一行输出为样例的编号。
第二行输出为所输入常数a,b,c对应的一元二次方程的标准形式,要求输出满足a>0。
第三行输出为所输入方程的根,分为三种情况:
1. 若方程满足Δ>0,即有两不等实根x1、x2,则按顺序(先小后大)输出这两个实根。
2. 若方程满足Δ=0,即有两相同实根x,则输出一个实根。
3. 若方程满足Δ<0,即有两共轭的虚根x1、x2,则输出两个虚根,虚部符号为正的(即u+vi形式)先输出,虚部符号为负的(x-yi形式)后输出。
以上输出均不输出数学上无意义或可省略的的符号,所有数值最多保留6位有效数字。每个样例之后都有一个空行分隔。
Sample Input
1 2 1
-1 2 -1
-5 2 -0.2
-3 2 0
3 0 12
2 4 4
0
Sample Output
Case 1 :
x^2 + 2x + 1 = 0
only one real root : -1
Case 2 :
x^2 - 2x + 1 = 0
only one real root : 1
Case 3 :
5x^2 - 2x + 0.2 = 0
only one real root : 0.2
Case 4 :
3x^2 - 2x = 0
two real roots : 0, 0.666667
Case 5 :
3x^2 + 12 = 0
two imaginary roots : 2i, -2i
Case 6 :
2x^2 + 4x + 4 = 0
two imaginary roots : -1+i, -1-i
HINT
输出方程格式的各种情况要想清楚,这一部分测试数据给的很全面。另一个就是浮点数的精度控制,这一部分sample给出了例子。
值得注意的是,linux下gcc编译的浮点数运算结果有-0,这是OJ系统Judge端使用的系统;而windows XP下的minGW编译器和VC6不会产生-0,只会输出0;但windows 7下的minGW编译器是能够产生-0的(确实很诡异)。因此使用windows XP的同学忽略了对结果为0的检测,程序需要对结果为0的情况进行全面考虑,确保正确的输出0。这个问题卡了好些同学好几天。
关于是否会产生-0,输出表达式0.0/-1的结果就能测试出来。浮点数从负数方向运算出结果为0,则浮点值为-0是符合C语言浮点数运算规则的,目前尚不清楚windows XP系统不能产生-0的原因。
以下是小白的我写的代码。。。。求找错误
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define X 0.000001
int i=1;
int main()
{
double a,b,c;
double t,t1,x1,x2,x3;
while(1)
{
scanf("%lf",&a);
if(fabs(a)<X) break;
else
{ scanf("%lf%lf",&b,&c);
t=b*b-4*a*c;
t1=sqrt(fabs(b*b-4*a*c));
x1=-t1/(2*a);
x2=+t1/(2*a);
x3=-b/(2*a);
if(fabs(fabs(a)-1)<X)printf("Case %d :\nx^2",i);
else printf("Case %d :\n%gx^2",i,fabs(a));
if(fabs(fabs(b)-1)>X)
{if(a>X)
{
if(b>X) printf(" + %gx",b);
else if(fabs(b)<X) ;
else printf(" - %gx",-b);
if(c>X) printf(" + %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" - %g = 0\n",-c);
}
if(a<X)
{
if(b>X) printf(" - %gx",b);
else if(fabs(b)<X) ;
else printf(" + %gx",-b);
if(c>X) printf(" - %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" + %g = 0\n",-c);
}
}
if(fabs(b-1)<X){if(a>X)
{
if(b>X) printf(" + x");
else if(fabs(b)<X) ;
else printf(" - x");
if(c>X) printf(" + %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" - %g = 0\n",-c);
}
if(a<X)
{
if(b>X) printf(" - x");
else if(fabs(b)<X) ;
else printf(" + x");
if(c>X) printf(" - %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" + %g = 0\n",-c);
}
}
if(fabs(b+1)<X)
{if(a>X)
{
if(b>X) printf(" + x");
else if(fabs(b)<X) ;
else printf(" - x");
if(c>X) printf(" + %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" - %g = 0\n",-c);
}
if(a<X)
{
if(b>X) printf(" - x");
else if(fabs(b)<X) ;
else printf(" + x");
if(c>X) printf(" - %g = 0\n",c);
else if(fabs(c)<X) printf(" = 0\n");
else printf(" + %g = 0\n",-c);
}
}
if(t>X)printf("two real roots : %g, %g\n\n",x3+x2,x3+x1);
if(fabs(t)<X){if(fabs(x1+x3)<X)printf("only one real root : 0\n\n");else printf("only one real root : %g\n\n",x1+x3);}
if(t<-X)
{
printf("two imaginary roots : ");
if(fabs(x3)<X&&x2>X&&fabs(x2-1)>X) printf("%gi, ",x2);
if(fabs(x3)<X&&x2>X&&fabs(x2-1)<X) printf("i, ");
if(fabs(x3)<X&&x2<-X&&fabs(x2+1)>X) printf("%gi, ",x2);
if(fabs(x3)<X&&x2<-X&&fabs(x2+1)<X) printf("-i, ");
if(fabs(x3)>X&&x2<-X&&fabs(x2+1)>X) printf("%g-%gi, ",x3,fabs(x2));
if(fabs(x3)>X&&x2<-X&&fabs(x2+1)<X) printf("%g-i, ",x3,fabs(x2));
if(fabs(x3)>X&&x2>X&&fabs(x2-1)<X) printf("%g+i, ",x3,x2);
if(fabs(x3)>X&&x2>X&&fabs(x2-1)>X) printf("%g+%gi, ",x3,x2);
/* second */
if(fabs(x3)<X&&x1>X&&fabs(x1-1)>X) printf("%gi\n\n",x1);
if(fabs(x3)<X&&x1>X&&fabs(x1-1)<X) printf("i\n\n");
if(fabs(x3)<X&&x1<-X&&fabs(x1+1)>X) printf("%gi\n\n",x1);
if(fabs(x3)<X&&x1<-X&&fabs(x1+1)<X) printf("-i\n\n");
if(fabs(x3)>X&&x1<-X&&fabs(x1+1)>X) printf("%g-%gi\n\n",x3,fabs(x1));
if(fabs(x3)>X&&x1<-X&&fabs(x1+1)<X) printf("%g-i\n\n",x3,fabs(x1));
if(fabs(x3)>X&&x1>X&&fabs(x1-1)<X) printf("%g+i\n\n",x3,x1);
if(fabs(x3)>X&&x1>X&&fabs(x1-1)>X) printf("%g+%gi\n\n",x3,x1);
}
}
i++;
}
}