题目描述
有形如:a x^3 + b x^2 + c x + 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) 之间一定有一个根
输入格式
一行,4 个实数 a, b, c, d
输出格式
一行,3 个实根,从小到大输出,并精确到小数点后 2 位。
输入输出样例
输入:1 -5 -4 20 输出:-2.00 2.00 5.00
解题思路:
一:暴力枚举,每次递增0.001,精度必须0.001,因为0.0001的话会重复结果,我们保留的位数是小数点后两位!
二:公式法。
三:二分法。
四:牛顿迭代法。
我自己做的是二分法,所以就只发二分法的题解了。
#include<iostream>
#include<iomanip>
using namespace std;
double a, b, c, d;
double f(double x);
double f(double x)
{
return x * x * x * a + x * x * b + x * c + d;
}
int main()
{
cin >> a >> b >> c >> d;
int i, o, p, ans = 0;
double x1, x2,x3;
for (i = -100; i <= 100; ++i) {
x1 = i;
x2 = x1 + 1;
if (!f(x1)) {
++ans;
cout << fixed << setprecision(2) << x1 << " ";
}
if (f(x1) * f(x2) < 0) {
x3 = (x1 + x2) / 2.0;
int flag = 1;
while (x2 - x1 >= 0.001) {
if (f(x3) * f(x2) < 0) x1 = x3;
else if (f(x3) * f(x2) > 0) x2 = x3;
else {
++ans;
flag = 0;
cout << fixed << setprecision(2) << x3 << " ";
break;
}
x3 = (x1 + x2) / 2.0;
}
if (flag) {
++ans;
cout << fixed << setprecision(2) << x3 << " ";
}
}
if (ans == 3) break;
}
return 0;
}