整数二分法模板
-
二分的本质不是单调性,
单调性的题目一定可以二分, 可以二分的题目不一定有单调性
-
二分的本质是边界
-
二分法用于查找, 每次都选择答案所在的区间再次进行查找, 当区间长度为 1时 , 就是答案
模板一
- 区间[l, r]被划分成 [l, mid] 和 [mid+1, r]时使用
int bsearch_1(int l, int r) {
while (l < r) {
int mid = l + r >> 1;
if (check[mid]) // check() 判断 mid是否满足性质
r = mid;
else
l = mid + 1;
}
return l;
}
模板二
- 区间[l, r]被划分成 [l, mid-1] 和 [mid, r]时使用
int bsearch_2(int l, int r) {
while (l < r) {
int mid = l + r + 1 >> 2; // 注意
if (check[mid]) // check() 判断 mid是否满足性质
l = mid; //需要加一
else
r = mid - 1;
}
}
如何选择模板
- 根据 check(mid)来判断 r和 l的取值范围
根据取值范围选择 mid是否有 + 1操作
mid归于左边, r = mid, mid选择 不 +1
mid归于右边, l = mid, mid选择 +1
浮点数二分法模板
double l=a,r=b; //a,b要根据具体二分的范围来指定
while(r-l>c){ //对于c的值,如果题目中要求保留4位小数,c取1e-6,如果题目中要求保留6位小数,那c取1e-8
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
例题
数的三次方根
给定一个浮点数 n,求它的三次方根。
输出格式
共一行,包含一个浮点数,表示问题的解。
注意,结果保留 6 位小数。
数据范围
−10000≤n≤10000−10000≤n≤10000
输入样例:
1000.00
输出样例:
10.000000
import java.io.*;
class Main{
public static void main(String[]args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
double n=Double.parseDouble(in.readLine());
double l=-1000;
double r=1000;
while(r-l>1e-8){
double mid=(l+r)/2;
if(mid*mid*mid<n) l=mid;
else r=mid;
}
System.out.printf("%.6f\n",l);
}
}