這是洛谷p1024,先上題目。
有形如:a x^3 + b x^2 + c x + d = 0這樣的乙個一元三次方程。給出該方程中各項的係數(a,b,c,d均為實數),並約定該方程存在三個不同實根(根的範圍在 -100至 100之間),且根與根之差的絕對值 ≥1。要求由小到大依次在同一行輸出這三個實根(根與根之間留有空格),並精確到小數點後2位。
一行,4個實數 a, b, c, da,b,c,d。
一行,3個實根,從小到大輸出,並精確到小數點後 2位。
輸入 #1複製
1 -5 -4 20
輸出 #1複製
-2.00 2.00 5.00
開始毫無頭緒,看了標籤後,發現是二分,只要找到乙個大於零的數,再找到乙個小於零的數,分別作為最左值和最右值,二分就能得答案,但問題又出現了,一元三次方程最多有三個解,即使找到了大於和小於零的數,也無法排除其他部分,最開始我想到的是在其餘部分再做尋找,直到找到三個解的範圍,但這樣不就和從前往後捋一樣了嗎?於是我便從網上查了一下一元三次方程,結果根據導數可以確定一元三次方程單調遞增、遞減的範圍,而每個範圍中的解至多乙個,所以在每個範圍中二分求解即可。還有的小問題在**中注釋。
下面上**。
#include#include#include
using
namespace
std;
double
a,b,c,d;
double san(double
n)double derta(double x,double y,double
z)void erfen(double l,double
r)
else
if(san(mid)<0
)
else
mid=(l+r)/2
; }
printf(
"%.2lf
",mid);}//
兩個二分是因為不確定單調遞增還是單調遞減
void erfen2(double l,double
r)
else
if(san(mid)<0
)
else
mid=(l+r)/2
; }
printf(
"%.2lf
",mid);
}int
main()
else
l=(-2*b-sqrt(derta(3*a,2*b,c)))*1.0/(6*a);
r=(-2*b+sqrt(derta(3*a,2*b,c)))*1.0/(6*a);
if(san(r)<0&&san(l)>0)
l=(-2*b+sqrt(derta(3*a,2*b,c)))*1.0/(6*a);
r=100.0
;
if(san(l)<=0
) }
return0;
}
一元三次方程求解
有形如 ax 3 bx 2 cx d 0這樣的乙個一元三次方程。給出該方程中各項的係數 a,b,c,d均為實數 並約定該方程存在三個不同實根 根的範圍在 100至100之間 且根與根之差的絕對值 1。要求由小到大依次在同一行輸出這三個實根 根與根之間留有空格 並精確到小數點後2位。輸入有多行測試資料...
一元三次方程求解
問題描述 有形如 ax 3 bx 2 cx d 0 這樣的乙個一元三次方程。給出該方程中各項的係數 a,b,c,d 均為實數 並約定該方程存在三個不同實根 根的範圍在 100至100之間 且根與根之差的絕對值 1。要求三個實根。輸入格式 四個實數 a,b,c,d 輸出格式 由小到大依次在同一行輸出這...
一元三次方程求解
有形如 ax3 bx2 cx d 0 這樣的乙個一元三次方程。給出該方程中各項的係數 a,b,c,d 均為實數 並約定該方程存在三個不同實根 根的範圍在 100至100之間 且根與根之差的絕對值 1。要求由小到大依次在同一行輸出這三個實根 根與根之間留有空格 並精確到小數點後2位。輸入格式 一行,4...