二分查找
789. 数的范围 - AcWing题库
- check函数
- (l+r(这里要不要+1))>> 1 ,要根据具体情况,如果是r = mid的话l+r就不用+1,l = mid的话就要+1
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, q;
cin >> n >> q;
for(int i = 0; i < n; i++) cin >> a[i];
while(q--){
int k;
cin >> k;
int l = 0, r = n - 1;
while(l < r){
int mid = (l + r) / 2;
if(a[mid] >= k) r = mid; // 找到第一个 >= k的元素
else l = mid + 1;
}
if(a[l] != k){
cout << "-1 -1" << endl;
continue;
}
cout << l << ' ';
l = 0, r = n - 1;
while(l < r){
int mid = (l + r + 1) / 2;
if(a[mid] <= k) l = mid; // 找到最后一个 <= k 的元素
else r = mid - 1;
}
cout << r << endl;
}
return 0;
}
浮点数二分
关键点在于当左边界和右边界足够接近,即差值小于1e-8(这里一般预留100倍的精度)时,则跳出循环
#include <bits/stdc++.h>
using namespace std;
int main(){
double n;
cin>>n;
double l=-100,r=100;
while(r-l>1e-8){//精度足够了
double mid=l+(r-l)/2;
if(mid*mid*mid-n<0){
l=mid;//简单在于不需要考虑边界,直接移到对应位置即可
}
else r=mid;//简单在于不需要考虑边界,直接移到对应位置即可
}
printf("%.6lf",mid);//保留6位小数,因此精度给100倍:1e-8
return 0;
}
二分答案
已知答案具有单调性,根据答案估计其上下界,然后进行二分,自定义check函数,在check函数中判断这个答案mid是否合法,然后移动边界进行二分。