问题描述
有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求三个实根。。
输入格式
四个实数:a,b,c,d
输出格式
由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位
样例输入
1 -5 -4 20
样例输出
-2.00 2.00 5.00
数据规模和约定
|a|,|b|,|c|,|d|<=10
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
typedef long long ll;
using namespace std;
const double eps=1e-9;
const int maxn=1010;
double a,b,c,d;
void get_x(double &x1,double &x2){
double A=3.0*a,B=2.0*b,C=c;
double tmp=sqrt(B*B-4.0*A*C);
x2=(-1*B+tmp)/(2.0*A);
x1=(-1*B-tmp)/(2.0*A);
}
int check(double x,int flag){
double tmp=a*x*x*x+b*x*x+c*x+d;
if(tmp<0){
if(!flag) return 1;
return 0;
}
else{
if(!flag) return 0;
return 1;
}
}
double solve(double l,double r,int flag){
double mid,ans;
while(r-l>=eps){
mid=(r+l)/2.0;
if(check(mid,flag)){
l=mid;
ans=mid;
}
else
r=mid;
}
return ans;
}
int main(){
scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
double x1,x2;
get_x(x1,x2);
int flag=1;
//printf("x1:%.2f x2:%.2f\n",x1,x2);
if(a>0) flag=0;
double ans1=solve(-1e9,x1,flag);
flag=flag^1;
double ans2=solve(x1,x2,flag);
flag=flag^1;
double ans3=solve(x2,1e9,flag);
printf("%.2f %.2f %.2f\n",ans1,ans2,ans3);
return 0;
}