P1024 一元三次方程求解 luogu

来源:互联网 发布:比邻聊天软件 编辑:程序博客网 时间:2024/05/02 13:34

题目描述

有形如: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。

输出格式:

一行,三个实根,并精确到小数点后2位。

输入输出样例

输入样例#1:
1 -5 -4 20
输出样例#1:
-2.00 2.00 5.00










数据不大,枚举法即可:
#include<cstdio>#include<cstdlib>#include<iostream>using namespace std;int main(){double a,b,c,d,x,fx;int i;cin>>a>>b>>c>>d;cout.precision(2);cout.setf(ios::fixed);for(i=-10000;i<=10000;x=(++i)/100.0){fx=a*x*x*x+b*x*x+c*x+d;if(fx>=-0.01&&fx<=0.01)cout<<x<<' '; }  return 0;}

当然不只这些,可以用二分法:
记方程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,
(1) 若a+0.0001>b或f(m)=0,则可确定根为m,并退出过程
(2)若f(a)*f(m)<0,则必然有f(m)*f(a)<0根在区间(a,m)中,故对区间重复该过程。
(3)若f(a)*f(m)<0,则必然有f(m)*f(b)<0,根在区间(m,b)中,对此区间重复该过程。

执行完毕即可得到精确到0.0001的根




#include<fstream>#include<iomanip>#include<iostream>using namespace std;float a,b,c,d;int n;float ans[4];float Equation(float x){return ((a*x+b)*x+c)*x+d;}void solve (float l,float r){if(Equation(l)*Equation(r)>0&&((r-1)<1||n>=2)) return; float mid=(l+r)/2;if(Equation(mid)<=1e-4&&Equation(mid)>=-1e-4){ans[++n]=mid;return ;}solve(l,mid);solve(mid,r);}int main(){cin>>a>>b>>c>>d;solve(-100,100);  cout<<fixed<<setprecision(2)<<ans[1]<<' '<<ans[2]<<' '<<ans[3]<<'\n';return 0;}





0 0