C2024级小小挑战2-#193. 「NOIP2001」一元三次方程求解 题解

$\huge\color{blue}\colorbox{none}{\#193. 「NOIP2001」一元三次方程求解 题解}$

题目描述

形如 $ax^3+bx^2+cx+d=0$ 的一元三次方程。给定 $a,b,c,d$ 系数,保证方程存在三个不同的实根,且根的范围在 $−100∼100$,且根与根之差的绝对值 $≥1$ 。请从小到大输出三个实根,精确到小数点后 $2$ 位。

提示:记方程 $f(x)=0$ ,若存在 $2$ 个数 $x1$ 和 $x2$ ,却 $x1 < x2$ ,$f(x1)*f(x2)<0$,则在 $(x1,x2)$ 之间一定存在一个根。

输入

$a,b,c,d $。

输出

小到大输出三个实根。

样例输入1

1 -5 -4 20

样例输出1

-2.00 2.00 5.00

这题思路其实非常简单,因为这道题只需要求 $-100 ∼ 100$ 的根,并且只需要保留两位小数。

所以......

只需要一个 $\small\color{green}\colorbox{none}{for循环暴力枚举}$ $-100 ∼ 100$ 的根,每次+=0.01就可以了!

在判断x是否为根时,可以设计一个函数(比如我就设计了 $f(a,b,c,d,x)$ 来判断是否为根)。

所以, $\large\color{green}\colorbox{none}{上代码}$ (本人亲测有效):

//the code is from chenjh
#include <bits/stdc++.h>
#include <cmath>
using namespace std;
double f(double a, double b, double c, double d, double x)//判断x是否为实根的函数
{
    double s;
    s = a * x * x * x + b * x * x + c * x + d;
    return s;
}
int main()
{
    double a, b, c, d;
    scanf("%lf%lf%lf%lf", &a, &b, &c, &d);//输入a,b,c,d
    for (double x = -100.00; x <= 100; x += 0.01) {//暴力枚举实根
        if (f(a, b, c, d, x) == 0) {//如果相等
            printf("%.2lf ", x);//输出x(两位小数)
        } else {
            if ((f(a, b, c, d, x) > 0 && f(a, b, c, d, x + 0.01) < 0) || (f(a, b, c, d, x) < 0 && f(a, b, c, d, x + 0.01) > 0)) {//如果在两根之间
                if (abs(f(a, b, c, d, x)) <= abs(f(a, b, c, d, x + 0.01))) {//判断哪个根更接近
                    printf("%.2lf ", x);
                } else {
                    printf("%.2lf ", x + 0.01);
                }
            }
        }
    }
    return 0;
}

代码结束

$\huge\color{blue}\colorbox{none}{记得点个赞!}$

$\huge\color{green}\colorbox{none}{感谢老师和同学的支持!}$

posted @ 2022-02-12 19:10  Chen_Jinhui  阅读(31)  评论(0)    收藏  举报  来源