題目描述
有形如: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?)?之間一定有一個根。
輸入格式
一行,4?個實數?a,b,c,d。
輸出格式
一行,3?個實根,從小到大輸出,并精確到小數點后?2?位。
輸入輸出樣例
輸入 #1
1 -5 -4 20
輸出 #1
-2.00 2.00 5.00
?
一:
確定根所在的長度為1的小區間
將根的范圍(-100, 100)劃分成長度為1的小片段 ?左右兩端為l r
滿足以下兩個條件之一:
①f(l)*f(r) < 0
②f(l) == 0
? ? f(r) == 0
二:
①根就是mid
f(mid) == 0?
②根在l和mid之間
f(l)*f(mid) < 0 ? ?r = mid
③根在mid和r之間
f(l)*f(mid) > 0 ? ?l = mid
#include<iostream>
using namespace std;double a, b, c, d;double f(double x)
{return a*x*x*x + b*x*x + c*x + d;
} void find(double l, double r)
{//區間長度足夠小時,區間內的任意一點都可以近似作為方程的根if(r-l < 0.001){printf("%.2f ", r); //輸出l也可以 return;}double mid = (l+r) / 2;//只有在區間長度還不夠小的情況下才需要檢查//如果中點恰好是根 if(f(mid) == 0){printf("%.2f ", mid);return;}//根在左半區間 if(f(l)*f(mid) < 0) find(l, mid); //根在右半區間 else find(mid, r);
}int main()
{cin>>a>>b>>c>>d; int cnt = 0;for(double i=-100; i<100, cnt != 3; ++i){//劃分區間i - i+1 長度為 1 if(f(i) == 0){printf("%.2f ", i);cnt++;continue;}if(f(i)*f(i+1) < 0){find(i, i+1);cnt++;}}return 0;
}
?