7891:一元三次方程求解
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
有形如: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(l)*f(r)<=0,其间必有根。
- 由于一定存在三个根,且两根的距离大于1,故从左往右,依次扫描、二分。
-
- 注意:因为此题要用到浮点,注意函数参数为Double型。
- 我就这么Wa了很久。
-
-
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<stack> #include<algorithm> using namespace std; #define MAXN #define MAXM #define INF 0x3f3f3f3f #define LL long long double a,b,c,d; double f(double x) { return a*x*x*x+b*x*x+c*x+d; } double dfs(double l,double r) { if(r-l<=0.001)return l; double mid=(l+r)/2; if(f(l)*f(mid)<=0)return dfs(l,mid); else return dfs(mid,r); } int main() { scanf("%lf%lf%lf%lf",&a,&b,&c,&d); double ans[5];int cnt=0; for(int i=-100;i<100;++i) { double l=i,r=i+1; if(f(l)==0) ans[++cnt]=l; else if(f(l)*f(r)<0) ans[++cnt]=dfs(l,r); if(cnt>=3)break; } printf("%0.2lf %0.2lf %0.2lf\n",ans[1],ans[2],ans[3]); }