錦囊1
枚舉加二分答案。
錦囊2
先用枚舉初步確定三個根的範圍,比如f[i]*f[i+1]<0則可知道[i,i+1]之間有一個根,然後再對於每個範圍內二分求根。
問題描述
有形如:ax3+bx2+cx+d=0 這樣的一個一元三次方程。給出該方程中各項的係數(a,b,c,d 均爲實數),並約定該方程存在三個不同實根(根的範圍在-100至100之間),且根與根之差的絕對值>=1。要求三個實根。。
輸入格式
四個實數:a,b,c,d
輸出格式
由小到大依次在同一行輸出這三個實根(根與根之間留有空格),並精確到小數點後2位
方法一:直接枚舉。
#include <cstdio>
#include <cmath>
int main(int argc, char** argv) {
double a, b, c, d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
double left = -100;
int cnt = 0;
for(double x = -100; cnt< 3 && x < 100; x += 0.01){
if( fabs(a*x*x*x + b*x*x + c*x + d) < 1e-5 ){
cnt++;
printf("%.2lf ",x);
}
}
return 0;
}
方法二:枚舉區間,看解存在於哪個區間裏,逐漸縮小區間範圍,確定解。
#include <cstdio>
#include <cmath>
double a, b, c, d;
double f(double x){
return a*x*x*x + b*x*x + c*x + d;
}
int main(int argc, char** argv) {
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
for(double i = -100; i < 100; i++){
double left = i, right = i+1;
if(fabs(f(left)) <= 1e-16){ //當左邊界已經是答案,防止重複得到兩次
printf("%.2lf ",left);
}else if(f(left) * f(right) < 0){
while( right - left >= 1e-5){
double mid = (left+right)/2;
if(f(left) * f(mid) <= 0) right = mid;
else left = mid;
}
printf("%.2lf ",left);
}
}
return 0;
}
樣例輸入
1 -5 -4 20
樣例輸出
-2.00 2.00 5.00
數據規模和約定
|a|,|b|,|c|,|d|<=10