PTA 编程题(C语言)-- 求一元二次方程的根

题目标题:求一元二次方程的根    题目作者:陈建海 浙江大学

本题目要求一元二次方程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;
}
更多PTA题目的的参考代码,可以在wx小程序里搜“PTA刷题助手”,或扫下面的二维码

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值