题目描述
题目来源 BUPT ACM
Problem Description
给定方程 8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y,请计算x在[0,100]范围内的解。
Input
输入数据首先是一个正整数T(1<=T<=100),表示有T组测试数据。
接下来T行,每行包含一个实数Y ( fabs(Y) <= 1e10 )。
Output
请计算并输出方程在范围[0,100]内的解,结果精确到小数点后4位。
如果无解,则请输出“No solution!
输入样例
2
100
-4
输出样例
1.6152
No solution!
思路
其实应该先证明一下,函数在[0,100]的区间中是单调递增的(这个自己求下导就可以了),根据零点存在性定理,要么有一个零点,要么没有零点,这个时候再用二分法,就合理很多。
Code
#include<iostream>
#include<cmath>
using namespace std;
int y;
double equation(double x){
return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6-y;
}
int main(){
int cnt;
cin>>cnt;
for(int i=1;i<=cnt;i++){
cin>>y;
double x1=0;
double x2=100;
double fx1=equation(x1);
double fx2=equation(x2);
if(fx1*fx2>0){ //判断方程是否有解
cout<<"No solution!"<<endl;
continue;
}
while(x2-x1>=0.000001){
double mid=(x2+x1)/2;
double fm=equation(mid);
if(fm<=0)
x1=mid;
else
x2=mid;
}
printf("%.4lf\n",x2);
}
system("pause");
return 0;
}
延伸
如果题目在所求区间当中,要求多个零点,则需要题目给出两个相邻零点间的最小距离,在每个区间中先应用零点存在性定理,找出存在解的区间,然后再使用二分法,就可以了。如洛谷P1024

AC Code
#include<iostream>
#include<cstdlib>
using namespace std;
double a,b,c,d;
double equation(double x){
return a*x*x*x+b*x*x+c*x+d;
}
int main(){
int cnt=0;
cin>>a>>b>>c>>d;
for(int i=-100;i<100;i++){
double x1=i;
double x2=i+1;
double fx1=equation(x1);
double fx2=equation(x2);
if(fx1==0){
printf("%.2lf ",x1);
cnt++;
}
if(fx1*fx2<0){
while(x2-x1>=0.001){
double mid=(x1+x2)/2;
double fm=equation(mid);
if(fm<=0){
x1=mid;
}else{
x2=mid;
}
}
printf("%.2lf ",x2);
cnt++;
}
if(cnt==3){
break;
}
}
system("pause");
return 0;
}