有形如:ax3+bx2+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)之間一定有一個
根。
一個三次方程的各項係數
三個解
1 -5 -4 20
-2.00 2.00 5.00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
這道題是一道明顯的二分題。
有題可知精度爲0.01,且三個解均在-100到100之間。由於範圍小,精度確定,所以我們可以用二分的方法去求解。
網上有一些題解,這裏我給出我的,和大家一起共享。
首先我們可以求導,必然的到兩個極值點,而這兩個極值點是由a,b,c,決定的,及求導後得到的一元二次方程的解。這兩個極值便是我們劃分區間的界限(f(x1),f(x2))我們便可以得到一個區間——(-100,f(x1))(f(x1),f(x2))(f(x2),100)
由函數圖象的性質可知若一個區間的兩端的函數值乘積小於0,則這個區間上必有解,這樣我們就可以一直二分下去,知道區間的兩端之差<=0.01時便可以退出了。
關於二分,有興趣的讀者,可以看一下我的下一篇文章——《二分哪些事兒》
……比較坑的是,我把a*x*x*x+b*x*x+c*x+d寫成了a*x*x*x+b*x*x+c+d導致我一直輸出錯誤,大家一定要注意!
++++++++++++++++++++++++代碼如下+++++++++++++++++++++++++++++
首先是用二分的:
#include <cstdio>
#include <cmath>
using namespace std;
double a,b,c,d;
double fang(double x)
{
return a*x*x*x+b*x*x+c*x+d;
}
double Bi_Search(double left,double right)//返回等於b的第一個
{
double last = -1,mid ;
while (left<=right)
{
double mid = left +(right-left)/2;
if(right-left<=0.01)
{
last = mid;
right = mid -1;
}
else
if(fang(mid)*fang(right)<0)
left = mid;
else
right = mid;
}
return last;
}
int main()
{
cin>>a>>b>>c>>d;
double aa=3*a,bb=2*b,x=100.00,y,m,n=-100.00;
y=(-bb+sqrt(bb*bb-4*aa*c))/(2*aa);
m=(-bb-sqrt(bb*bb-4*aa*c))/(2*aa); cout<<y<<" "<<m<<endl;
double x1=Bi_Search(n,m),x2=Bi_Search(m,y),x3=Bi_Search(y,x);
printf("%.2lf %.2lf %.2lf",x1,x2,x3);
return 0;
}
這裏還有一個用公式直接求解的:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
void mmax(double &x,double &y,double &z)
{
double a[3];
a[0]=x,a[1]=y,a[2]=z;
sort(a,a+3);
x=a[0],y=a[1],z=a[2];
return ;
}
int main()
{
double A,B,C,a,b,c,d;
cin>>a>>b>>c>>d;
A=b*b-3*a*c;
B=b*c-9*a*d;
C=c*c-3*b*d;
double t=2*A*b-3*a*B;
t/=2*sqrt(A*A*A);
double cr=acos(t);
double x_1,x_2,x_3;
x_1=(-b-2*sqrt(A)*cos(cr/3))/3*a;
x_2=(-b+sqrt(A)*(cos(cr/3)+sqrt(3)*sin(cr/3)))/3*a;
x_3=(-b+sqrt(A)*(cos(cr/3)-sqrt(3)*sin(cr/3)))/3*a;
mmax(x_1,x_2,x_3);
printf("%0.2lf %0.2lf %0.2lf",x_1,x_2,x_3);
return 0;
}