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)之间一定有一个根。
要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后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 20 0 0 0 0
Sample Output
-2.00 2.00 5.00
/*
解题报告:对F(x)=A^3+B^2+C*X+D 对F(X)求导得到F'(X)=3*X*X+2*B*X+C,在求导得到
F''(x)=6*A*X+2*B=0 可求出X, 则F'(X)是F'函数的极值。用二分可求出F的
极值。再用二分求出方程的解。
*/
//标程:
#include<stdio.h> #include<string.h> double a,b,c,d,s,s1,s2,s3,s4,s5; double ans,ans1; int flag; double f(double x) { return 3*a*x*x+2*b*x+c; } double f1(double x) { return a*x*x*x+b*x*x+c*x+d; } double fun(double l,double r) { double mid; while(r-l>1e-5) { mid=(r+l)/2; if(a>0) { if(f(mid)>=0 && s>l) l=mid; if(f(mid)<0 && s>l) r=mid; if(f(mid)>=0 && l>s) r=mid; if(f(mid)<0 && l>s) l=mid; } else { if(f(mid)>=0 && s>l) r=mid; if(f(mid)<0 && s>l) l=mid; if(f(mid)>=0 && l>s) l=mid; if(f(mid)<0 && l>s) r=mid; } } return r; } double fun2(double l,double r) { double mid; flag++; while(r-l>1e-7) { mid=(r+l)/2; if(flag==1 || flag==3) { if(ans>ans1) { if(f1(mid)>=0) r=mid; else l=mid; } else { if(f1(mid)>=0) l=mid; else r=mid; } } if(flag==2) { if(ans>ans1) { if(f1(mid)>=0) l=mid; else r=mid; } else { if(f1(mid)>=0) r=mid; else l=mid; } } } return r; } int main() { //freopen("a.txt","r",stdin); while(scanf("%lf%lf%lf%lf",&a,&b,&c,&d)) { if(a==0 && b==0 && c==0 && d==0) break; s=-1*b/(3*a); s1=fun(-110,s-0.00001); s2=fun(s+0.000001,110); ans=f1(s1), ans1=f1(s2); flag=0; s3=fun2(-110,s1); s4=fun2(s1,s2); s5=fun2(s2,110); printf("%.2lf %.2lf %.2lf\n",s3,s4,s5); } return 0; }