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}{感谢老师和同学的支持!}$

浙公网安备 33010602011771号