一元三次方程求解
题目描述
链接:https://ac.nowcoder.com/acm/problem/16694
来源:牛客网
有形如:ax3+bx2+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)之间一定有一个根。
输入描述
一行,4个实数A,B,C,D。
输出描述
一行,3个实根,并精确到小数点后2位。
示例1
输入
1 -5 -4 20
输出
-2.00 2.00 5.00
分析
因为根于根之差的绝对值>=1,所以以1为单位长度进行二分最合适,即x2 - x1 = 1。
在本题中,最好将所有数据定义为double/float类型,以免出现错误。
以a = x * y为例,当x,y其中只要有一个为float/double类型时,x*y的结果(不是指的a)就是float/double类型;当x,y都为int类型时,即使a被定义为float/double类型,最后a还是int类型。
#include <iostream>
using namespace std;
float a, b, c, d;
float fun(float i) //i的类型一定要是float/double
{
return i * i * i * a + i * i * b + i * c + d;
}
int main()
{
cin >> a >> b >> c >> d;
for (float i = -100; i < 100; ++i)
{
if (fun(i) * fun(i + 1) <= 0)
{
if (fun(i) == 0)
{
printf("%.2f ", i);
}
else if (fun(i + 1) == 0)
{
printf("%.2f ", i + 1);
++i; //很重要,避免下次重复计算
}
else //二分
{
float l = i, r = i + 1;
float mid;
while (r - l >= 1e-3)
{
mid = (l + r) / 2.0;
if (fun(mid) == 0)
{
printf("%.2f ", mid);
break;
}
else if (fun(l) * fun(mid) < 0)
r = mid;
else if (fun(mid) * fun(r) < 0)
l = mid;
}
if (fun(mid) != 0)
printf("%.2f ", mid);
}
}
}
return 0;
}