Problem D: 求一元二次方程的根

Problem D: 求一元二次方程的根
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
1.输出方程格式的各种情况要想清楚,这一部分测试数据给的很全面。另一个就是浮点数的精度控制,这一部分sample给出了例子。
2. 值得注意的是,linux下gcc编译的浮点数运算结果有-0,这是OJ系统Judge端使用的系统;而windows XP下的minGW编译器和VC6不会产生-0,只会输出0;但windows7下的minGW编译器是能够产生-0的(确实很诡异)。因此使用windows XP的同学忽略了对结果为0的检测,程序需要对结果为0的情况进行全面考虑,确保正确的输出0。这个问题卡了好些同学好几天。
3.关于是否会产生-0,输出表达式0.0/-1的结果就能测试出来。浮点数从负数方向运算出结果为0,则浮点值为-0是符合C语言浮点数运算规则的,目前尚不清楚windowsXP系统不能产生-0的原因。

Append Code

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    double a,b,c,delta;
    int flag=0;
    while(1)
    {
        scanf("%lf",&a);
        if(a==0)
            break;
        scanf("%lf%lf",&b,&c);
        if(a<0)
        {
            a = -a;
            b = -b;
            c = -c;
        }
        delta = b*b-4*a*c;
        if(fabs(delta)<0.001)
            delta = 0;
        flag++;
        if(flag==1)
            printf("Case %d :\n",flag);
        else
            printf("\nCase %d :\n",flag);
        if(fabs(a-1)<0.001&&fabs(b-1)<0.001&&c>0)
            printf("x^2 + x + %g = 0\n",c);
        if(fabs(a-1)<0.001&&fabs(b-1)<0.001&&c<0)
            printf("x^2 + x - %g = 0\n",-c);
        if(fabs(a-1)<0.001&&fabs(b-1)<0.001&&fabs(c)<0.001)
            printf("x^2 + x = 0\n");
        if(fabs(a-1)<0.001&&fabs(b)<0.001&&c>0)
            printf("x^2 + %g = 0\n",c);
        if(fabs(a-1)<0.001&&fabs(b)<0.001&&c<0)
            printf("x^2 - %g = 0\n",-c);
        if(fabs(a-1)<0.001&&fabs(b)<0.001&&fabs(c)<0.001)
            printf("x^2 = 0\n");
        if(fabs(a-1)<0.001&&fabs(b+1)<0.001&&c>0)
            printf("x^2 - x + %g = 0\n",c);
        if(fabs(a-1)<0.001&&fabs(b+1)<0.001&&c<0)
            printf("x^2 - x - %g = 0\n",-c);
        if(fabs(a-1)<0.001&&fabs(b+1)<0.001&&fabs(c)<0.001)
            printf("x^2 - x = 0\n");
        if(fabs(a-1)<0.001&&fabs(b-1)>0.001&&b>0&&c>0)
            printf("x^2 + %gx + %g = 0\n",b,c);
        if(fabs(a-1)<0.001&&fabs(b-1)>0.001&&b>0&&c<0)
            printf("x^2 + %gx - %g = 0\n",b,-c);
        if(fabs(a-1)<0.001&&fabs(b-1)>0.001&&b>0&&fabs(c)<0.001)
            printf("x^2 + %gx = 0\n",b);
        if(fabs(a-1)<0.001&&fabs(b+1)>0.001&&b<0&&c>0)
            printf("x^2 - %gx + %g = 0\n",-b,c);
        if(fabs(a-1)<0.001&&fabs(b+1)>0.001&&b<0&&c<0)
            printf("x^2 - %gx - %g = 0\n",-b,-c);
        if(fabs(a-1)<0.001&&fabs(b+1)>0.001&&b<0&&fabs(c)<0.001)
            printf("x^2 - %gx = 0\n",-b);
        if(fabs(a-1)>0.001&&fabs(b-1)<0.001&&c>0)
            printf("%gx^2 + x + %g = 0\n",a,c);
        if(fabs(a-1)>0.001&&fabs(b-1)<0.001&&c<0)
            printf("%gx^2 + x - %g = 0\n",a,-c);
        if(fabs(a-1)>0.001&&fabs(b-1)<0.001&&fabs(c)<0.001)
            printf("%gx^2 + x = 0\n",a);
        if(fabs(a-1)>0.001&&fabs(b)<0.001&&c>0)
            printf("%gx^2 + %g = 0\n",a,c);
        if(fabs(a-1)>0.001&&fabs(b)<0.001&&c<0)
            printf("%gx^2 - %g = 0\n",a,-c);
        if(fabs(a-1)>0.001&&fabs(b)<0.001&&fabs(c)<0.001)
            printf("%gx^2 = 0\n",a);
        if(fabs(a-1)>0.001&&fabs(b+1)<0.001&&c>0)
            printf("%gx^2 - x + %g = 0\n",a,c);
        if(fabs(a-1)>0.001&&fabs(b+1)<0.001&&c<0)
            printf("%gx^2 - x - %g = 0\n",a,-c);
        if(fabs(a-1)>0.001&&fabs(b+1)<0.001&&fabs(c)<0.001)
            printf("%gx^2 - x = 0\n",a);
        if(fabs(a-1)>0.001&&fabs(b-1)>0.001&&b>0&&c>0)
            printf("%gx^2 + %gx + %g = 0\n",a,b,c);
        if(fabs(a-1)>0.001&&fabs(b-1)>0.001&&b>0&&c<0)
            printf("%gx^2 + %gx - %g = 0\n",a,b,-c);
        if(fabs(a-1)>0.001&&fabs(b-1)>0.001&&b>0&&fabs(c)<0.001)
            printf("%gx^2 + %gx = 0\n",a,b);
        if(fabs(a-1)>0.001&&fabs(b+1)>0.001&&b<0&&c>0)
            printf("%gx^2 - %gx + %g = 0\n",a,-b,c);
        if(fabs(a-1)>0.001&&fabs(b+1)>0.001&&b<0&&c<0)
            printf("%gx^2 - %gx - %g = 0\n",a,-b,-c);
        if(fabs(a-1)>0.001&&fabs(b+1)>0.001&&b<0&&fabs(c)<0.001)
            printf("%gx^2 - %gx = 0\n",a,-b);
        if(delta>0)
            printf("two real roots : %g, %g\n",(-b-sqrt(delta))/(2*a),(-b+sqrt(delta))/(2*a));
        if(delta==0)
        {
            if(fabs(-b/(2*a))<0.001)
                printf("only one real root : 0\n");
            else
            printf("only one real root : %g\n",-b/(2*a));
        }
        if(delta<0)
        {
            if(fabs(-b/(2*a))<0.001&&fabs(sqrt(-delta)/(2*a)-1)>0.001)
                printf("two imaginary roots : %gi, %gi\n",sqrt(-delta)/(2*a),-sqrt(-delta)/(2*a));
            if(fabs(-b/(2*a))<0.001&&fabs(sqrt(-delta)/(2*a)-1)<0.001)
                printf("two imaginary roots : i, -i\n");
            if(fabs(-b/(2*a))>0.001&&fabs(sqrt(-delta)/(2*a)-1)<0.001)
                printf("two imaginary roots : %g+i, %g-i\n",-b/(2*a),-b/(2*a));
            if(fabs(-b/(2*a))>0.001&&fabs(sqrt(-delta)/(2*a)-1)>0.001)
                printf("two imaginary roots : %g+%gi, %g%gi\n",-b/(2*a),sqrt(-delta)/(2*a),-b/(2*a),-sqrt(-delta)/(2*a));
        }
    }
    return 0;
}

第一个百行代码。。。。。。。。暴力讨论,就这样。。。

优皇的AC码:

#include<stdio.h>
#include<math.h>
 
double zero(double ans) {
    if (fabs(ans) < 1e-6)
        return 0;
    else
        return ans;
}
 
void printeq(double a, double b, double c) {
    if (a != 1)
        printf("%g", a);
    printf("x^2");
    if (b != 0)
    {
        putchar(' ');
        putchar(b > 0 ? '+' : '-');
        putchar(' ');
        if (b != 1 && b != -1)
            printf("%g", fabs(b));
        printf("x");
    }
    if (c != 0)
    {
        putchar(' ');
        putchar(c > 0 ? '+' : '-');
        printf(" %g", fabs(c));
    }
    puts(" = 0");
}
 
double judge(double a, double b, double c) {
    double ans = zero(b * b - 4 * a * c);
    return ans;
}
 
void cal(double a, double b, double c, double j) {
    double ans1, ans2;
    ans1 = zero(-b / 2 / a);
    if (j > 0)
    {
        ans1 = (-b - sqrt(j)) / 2 / a;
        ans2 = (-b + sqrt(j)) / 2 / a;
        printf("two real roots : %g, %g\n", zero(ans1), zero(ans2));
    }
    else if (j == 0)
    {
        printf("only one real root : %g\n", ans1);
    }
    else
    {
        j = zero(sqrt(-j) / 2 / a);
        printf("two imaginary roots : ");
        if (ans1 != 0)
            printf("%g+", ans1);
        if (j != 1)
            printf("%g", j);
        printf("i, ");
        if (ans1 != 0)
            printf("%g", ans1);
        putchar('-');
        if (j != 1)
            printf("%g", j);
        printf("i\n");
    }
}
 
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int cnt = 1;
    double a, b, c, j;
    while (scanf("%lf%lf%lf", &a, &b, &c))
    {
        if (a == 0)
            break;
        if (a < 0)
        {
            a = -a;
            b = -b;
            c = -c;
        }
        if (cnt > 1)
            puts("");
        printf("Case %d :\n", cnt++);
        printeq(a, b, c);
        j = judge(a, b, c);
        cal(a, b, c, j);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值