高中数学也好,初中数学也好,老师都讲过二分法,这类题目多多少少也做过。比如计算根号2的值等等。
计算根号2的值(近似的)
思想还是二分法
//计算根号2的近似值
const double eps=1e-5;
double f(double x){
return x*x;
}
double calSort(){
double left=1,right=2,mid;//区间为[1,2]
while(right-left>eps){
mid=(left+right)/2;
if(f(mid)>2)
right=mid;
else
left=mid;
}
return left;
}
int main(){
printf("%lf",calSort());
return 0;
}
稍加总结,可以得出
二分法模板
const double eps=1e-5;
double f(double x){
return ...;//这里替换成需要的式子就行
}
double solve(double L,double R){
double left=L,right=R,mid;
while(right-left>eps){
mid=(left+right)/2;
if(f(mid)>0){
right-mid;
}else{
left=mid;
}
}
return mid;
}
例子
装水问题
寻找水面高度h与面积比例r的关系
const int pi=acos(-1.0);
const double eps=1e-5;
double f(double R,double h){
double alpha=(2*acos(R-h)/R);
double L=2*sqrt(R*R-(R-h)*(R-h));
double s1=alpha*R*R/2-L*(R-h)/2;
double s2=pi*R*R/2;
return s1/s2;
}
double solve(double R,double r){
double left=0,right=R,mid;
while(right-left>eps){
mid=(left+right)/2;
if(f(R,mid)>r){
right=mid;
}else{
left=mid;
}
}
return mid;
}
int main(){
double R,r;
scanf("%lf%lf",&R,&r);
printf("%.4lf\n",solve(R,r));
return 0;
}