算法训练 一元三次方程求解 (分情况二分)

问题描述
  有形如:ax 3+bx 2+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
#include
#include
#include
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;
}

你可能感兴趣的:(.....二分)