二分查找
整数二分
一、基本思路
1.查边界,用二分
2.每次都保证区间里覆盖到答案,然后二分直到区间为一的时候,就是答案
3.注意边界问题,mid = l + r (+ 1) >> 1 加不加1需要判断
二、整数二分模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| bool check(x){ }
int bsearch_1(int l, int r){ while(l < r){ int mid = l + r >> 1; if(check(mid)) r = mid; else l = mid + 1; } return l; }
bool check(x){}
int bsearch_2(int l, int r){ while(l < r){ int mid = l + r + 1 >> 1; if(check(mid)) l = mid; else r = mid - 1; } return 1; }
|
三、例题
例题一:数的范围
本题转载自acwing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
#include<iostream> using namespace std;
const int N = 1e6 + 10; int q[N]; int n,m;
int main(){ scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) scanf("%d", &q[i]); while(m --){ int x; scanf("%d", &x); int l = 0, r = n - 1; while(l < r){ int mid = l + r >> 1; if(q[mid] >= x) r = mid; else l = mid + 1; } if(q[l] != x) cout<<"-1 -1"<<endl; else { cout<<l<<" ";
int l = 0, r = n - 1; while(l < r){ int mid = l + r + 1 >> 1; if(q[mid] <= x) l = mid; else r = mid - 1; } cout<<l<<endl; } } return 0; }
|
浮点数二分
一、浮点数二分模板
1 2 3 4 5 6 7 8 9 10 11 12
| bool check(double x){} double bsearch_3(double l, double r){ const double eps = 1e-6; while(r - l > eps){ double mid = l + r >> 1; if(check(mid)) r = mid; else l = mid; } return 1; }
|
二、例题
例题一:数的三次方根
本题转载自acwing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
输入格式 共一行,包含一个浮点数 n。
输出格式 共一行,包含一个浮点数,表示问题的解。
注意,结果保留 6 位小数。
数据范围 −10000≤n≤10000*/ #include<iostream> #include <math.h> using namespace std;
double n;
int main(){ const double eps = 1e-8; cin>>n;
double l = -10000, r = 10000; while(r - l > eps){ double mid = (l + r) / 2; if(pow(mid,3) >= n) r = mid; else l = mid; } printf("%f", l);
return 0; }
|