1.2 二分
本次主要讲到整数二分和浮点数二分,整数二分要考虑到边界问题,浮点数二分较为容易,可以采用精度控制法和循环次数控制法。
1.2.1 整数二分
- 二分和单调性的关系(有单调性的 一定可以二分)
- 二分是确定区间上满足某个性质的边界点
- 二分的模板是一定能找到解的
//区间[l,r]被划分为[l, mid]和[mid + 1, r]时使用
int bsearsh_1(int l,int r)
{
while(l < r)
{
int mid= l+r>>1;
if(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>>1;
if(check(mid)) l = mid;
else r = mid -1;
}
return l;
}
步骤
- 先写check函数
- 看下l r 更新方式 如果是 l =mid (板子1 mid补上1) 否则是 r =mid
- 补上加1防止进入死循环
- 习题 789 数的范围
#include<iostream>
using namespace std;
const int N=1e6+10;
int q[N];
int main()
{
int n,m,x;
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&q[i]);
}
while(m--){
scanf("%d",&x);
int l=0,r=n-1,mid;
while(l<r){
mid=l+r>>1;
if(q[mid]>=x) r=mid;
else l= mid+1;
}
if(q[l]!=x)cout<<"-1 -1\n";
else {
cout<<l<<" ";
int l=0,r=n-1,mid;
while(l<r){
mid=(l+r+1)>>1;
if(q[mid]<=x) l=mid;
else r =mid-1;
}
cout<<l<<endl;
}
}
}
1.2.2 浮点数二分
- 不用考虑处理边界问题,较容易。
- 经验值:误差区间比题目要求多乘
#include<iostream>
using namespace std;
const double t=1e-8;
int main()
{
//cout<<t;
double a,l=-10000,r=10000,mid;
cin>>a;
while((r-l)>t){
mid=(l+r)/2;
if(mid*mid*mid<=a) l=mid;
else r=mid;
}
printf("%.6lf",l);
}