二分一般分为整数二分和实数二分,整数二分相对较为麻烦,要考虑边界问题
整数二分
二分就是一个有限序列存在一个性质可以将这个序列分成左右两个序列,这样不断进行缩小目标范围,最终确定位置的一个过程。 一般使用的性质就是有序性,但是二分不一定有序,有序一般都二分
步骤
- 定义左右边界
- 在一个循环体中,定义mid为区间中点
- 如果说左边满足性质,则将右边界更新为mid,反之亦然
- 最后更新的l和r是一样的
注意:二分时极易出现死循环的状态,并且有时会出现要二分区间的题目,所以下面提供两个模板(以有序序列为例)
模板
寻找左边界
int l=0,r=n-1;
while(l<r)
{
int mid=l+r>>1;
if(m[mid]>=x) r=mid;
else l=mid+1;
}
寻找右边界
int l=0,r=n-1;
while(l<r)
{
int mid=l+r+1>>1;
if(m[mid]<=x) l=mid;
else r=mid-1;
}
实数二分
实数二分相对简单,没有边界问题,这里以实数的三次方根为例 题目和讲解
模板
double n;
cin>>n;
double l=-100,r=100;
while(r-l>1e-8) //精度根据题意来定,要求六位就定到1e-8
{
double mid=(l+r)/2;
if(mid*mid*mid>=n) r=mid;
else l=mid;
}
printf("%.6f",l);
return 0;