題目
有形如:這樣的一個一元三次方程。給出該方程中各項的系數(shù)(a,b,c,d均為實數(shù)),并約定該方程存在三個不同實根(根的范圍在?100至100之間),且根與根之差的絕對值≥1。要求由小到大依次在同一行輸出這三個實根(根與根之間留有空格),并精確到小數(shù)點后2位。
提示:記方程,若存在2個數(shù)和,且?,,則在(,?)?之間一定有一個根。
輸入輸出格式
輸入格式
一行,4個實數(shù)a,b,c,d。
輸出格式
一行,3個實根,從小到大輸出,并精確到小數(shù)點后2位。
輸入輸出樣例
輸入樣例
1 -5 -4 20
輸出樣例
-2.00 2.00 5.00
解析
此題目考慮使用二分的方法求解。使用零點存在性定理:對連續(xù)函數(shù)f(x)若有f(a)*f(b)<0(a<b)則f(x)在區(qū)間(a,b)上至少存在一個解。這樣就可以判斷在一個區(qū)間中是否有解。
令條件為f(x)>=0,顯然在上述區(qū)間(a,b)上條件具有單調(diào)性:在根的一側(cè)f(x)都是負(fù)數(shù),另一側(cè)f(x)都是正數(shù)。題目中說明了任意兩根之差不小于1,那么可以把[-100,100]等分成若干份[i,i+1)(這里左閉右開是為了防止端點處是零點導(dǎo)致得到重復(fù)解)。在每個小段中至多只有一個零點,這意味著這個區(qū)間上的條件具有單調(diào)性。
于是一個定義在實數(shù)區(qū)間上的二分方法就得出:如果中點的函數(shù)值和某端點的正負(fù)性相同,那么零點一定在中點的另一側(cè)。
注意:實數(shù)之間不能直接比較是否相等,而是判斷之間的差值是否小于eps。文章來源:http://www.zghlxwxcb.cn/news/detail-831185.html
同時二分的次數(shù)和精度有關(guān),但是考慮每次二分的區(qū)間都可以減少一半,縮減的速度還是很快的,因此也是對數(shù)級別。與整數(shù)區(qū)間二分有一點微妙的區(qū)別,實數(shù)區(qū)間上的二分需要確定好精度。題目要求輸出與保留兩位小數(shù),那么可以在二分端點相差不超過時停止二分來確保精度。?文章來源地址http://www.zghlxwxcb.cn/news/detail-831185.html
#include<iostream>
#include<cstdio>
#include<cmath>
#define eps 1e-4
using namespace std;
double a,b,c,d;
double f(double x){
return a*pow(x,3)+b*pow(x,2)+c*x+d;//計算函數(shù)值
}
int main(){
cin>>a>>b>>c>>d;
for(int i=-100;i<=100;i++){
double l=i,r=i+1,mid;
if(fabs(f(l))<eps){//端點處處理,左閉右開
printf("%.2lf ",l);
}
else if(fabs(f(r))<eps){
continue;
}
else if(f(l)*f(r)<0){//在區(qū)間(l,r)上執(zhí)行二分
while(r-l>eps){
mid=(l+r)/2;
if(f(mid)*f(r)>0){//如果f(mid)和f(r)正負(fù)性相同,那么零點在mid左側(cè)
r=mid;
}
else{//否則在另一側(cè)
l=mid;
}
}
printf("%.2lf ",l);
}
}
}
到了這里,關(guān)于P1024 [NOIP2001 提高組] 一元三次方程求解題解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!