我不想再做笨蛋了|

wenli7363

园龄:3年3个月粉丝:7关注:6

【ACWING】二分算法

二分查找

  1. 二分主要分为整数实数两种问题,最麻烦的是整数二分问题,因为涉及到的边界问题比较多

  2. 二分大多是利用了单调性,有单调性的一定可以二分,但是有些二分可以没有单调性

  3. 二分的本质按y总说的,就是利用一个边界点,将其分为两部分,一部分满足一定条件,另一部分不满足这个条件

整数二分两种模板

注意下图中我没有标注mid的位置。因为mid就是图中标记为true/false的点

int l=0,r=len-1;
//模板1
int bseach_1(int l,int r)
{
while(l<r)
{
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
return l;
}
//模板2
int bseach_2(int l,int r)
{
while(l<r)
{
//这里一定要+1,不然若r=l+1,mid=l+r时,计算出来取下整,得到mid=l,这时候会死循环。
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
return l;
}

如何区分两种模板捏?

  • 先写个int mid=l+r>>1;
  • 判断如何写check函数,(单调性用的多)
  • 先画图判断check(mid)==truer,l如何更新
  • 确定完之后,根据L,R的更新方式,看看mid处是否+1

二分模板一定有解,如果有无解的情况,是题目设置的问题

二分会在l=r时退出循环,最终判断就是看q[l]的值是否是符合题意的,不符合即为无解


浮点数二分

浮点数二分的退出条件就是最后的区间小于一定程度,比如r-l<1e-8 的时候,我们认为q[l]就是我们想要的值。

这里 1e-8这个值是不定的,为了适应精度问题,一般多两位,比如说要求保留5位小数,最后要小于1e-7

而且这时候我们不需要考虑边界问题,所以只有一种模板

以求平方根的结果为例子

int main(){
double x;
cin >> x;
double l = 0,r = 10000;
//第二种写法就是直接for(int i =0;i<100;i++) 这样子迭代下去
while(r-l>1e-8)
{
double mid =(l+r)/2;
if (mid*mid>=x) r=mid;
else l=mid;
}
printf("%lf\n",l);
return 0;
}
posted @   wenli7363  阅读(46)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起