大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn
😁 P1024 一元三次方程求解
描述
有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。
给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
输入
一行,包含四个实数a,b,c,d,相邻两个数之间用单个空格隔开。
输出
一行,包含三个实数,为该方程的三个实根,按从小到大顺序排列,相邻两个数之间用单个空格隔开,精确到小数点后2位。
样例输入
1.0 -5.0 -4.0 20.0
样例输出
-2.00 2.00 5.00
分析
记方程f(x)=0
,若存在2个不同的数x1
和x2
,且f(x1)*f(x2)<0
,则在(x1,x2)
之间一定有一个根。
当已知区间(a,b)
内有一个根时,可用二分法求根。若区间(a,b)
内有根,则必有f(a)*f(b)<0
。重复执行如下的过程。
令m=(a+b)/2
- 若
a+0.0001>b
或f(m)=0
,则可以确定根为m
,并退出过程; - 若
f(a)*f(m)<0
,则必然有f(m)*f(a)<0
根在区间(a,m)
中,故对区间重复该过程; - 若
f(a)*f(m)>0
,则必然有f(m)*f(b)<0
,根在区间(m,b)
中,对此区间重复该过程。执行完毕,就可以得到精确到0.0001
的根。
代码实现
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
long double a, b, c, d;
long double f(long double x)
{
return a*x*x*x + b*x*x + c*x + d;
}
long double Calculator(long double low, long double high)//二分
{
long double middle = (low + high) / 2;
if (abs(low - high) <= 0.0001)
{
return middle;
}
if (f(low)*f(middle) < 0)
{
return Calculator(low, middle);
}
else
{
return Calculator(middle, high);
}
}
int main()
{
cin >> a >> b >> c >> d;
long double L1, L2;
L1 = (-2 * b - sqrt(4 * b*b - 4 * 3 * a*c)) / (2 * 3 * a);//计算极值点
L2 = (-2 * b + sqrt(4 * b*b - 4 * 3 * a*c)) / (2 * 3 * a);
cout << fixed << setprecision(2) << Calculator(-100, L1) << " " << Calculator(L1, L2) << " " << Calculator(L2, 100);
}
提交结果
2020年9月26日更
大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn