一元三次方程求解

来源:互联网 发布:仁化网络问政平台 编辑:程序博客网 时间:2024/04/27 18:35

Problem Description

有形如:ax^3+bx^2+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)之间一定有一个根。

Input

输入有多行测试数据,每行为四个系数a,b,c,d,输入以0 0 0 0结束。

Output

对于每组测试数据,输出一个三个实根(根与根之间留有空格),并精确到小数点后2位。

Sample Input

1 -5 -4 200 0 0 0

Sample Output

-2.00 2.00 5.00
/*思路:若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个根。可以用二分法来写,查找。范围在-100到100,三个根。先对一元三次方程求导,得到极值(驻点)利用高数方法就分成三部分,分别在三部分里面求根。缩小范围*/ #include<cstdio>#include<cmath>#include<iostream>using namespace std;double a,b,c,d;double fun(double x){    return a*x*x*x+b*x*x+c*x+d;}double f(double x1,double x2)//二分法查找{     double mid;     while(1)    {      mid=(x1+x2)/2;            if( fabs(x1-x2 )<1E-8) return mid;                         else                {                     if(fun(mid) ==0)  return mid;                       else  if(fun(x1)*fun(mid )<0) x2=mid;                       else  x1=mid;               }    } }int main(){   double x1,x2;    while( scanf("%lf%lf%lf%lf",&a,&b,&c,&d)!=EOF)   {        if(!(a&&b&&c&&d)) break;                 //一元三次变为一元二次,求导,降幂,得f'(x)=3*a*x*x+2*b*x+c;               //解方程f'(x) 一元二次求根公式               x1=(-2*b-sqrt(4*b*b-12*a*c))/(6*a);         x2=(-2*b+sqrt(4*b*b-12*a*c))/(6*a);                  //得到两个实根x1、x2,也就是f(x)的极值点(驻点)。                        //f(x)=0的3个根应在区间[-100,x1]、[x1,x2]、[x2,100]中。           printf("%.2lf %.2lf %.2lf\n",f(-100,x1),f(x1,x2),f(x2,100));    }    return 0;}

0 0
原创粉丝点击