二分

 

二分的本质是丢弃,即整体可以划分为两部分,一部分满足这种性质,另一部分不满足这种性质,舍弃掉不满足这种性质的一半,从另一半开始寻找,边界在这个过程进行了改变。

二分的关键是边界点的二分,二分可以找到满足这个性质的边界点或不满足这个性质的边界点。

整数二分(需要取整,考虑边界问题)二分有界且单调

 

求边界点A或边界点B分别有两个板子。

(1)二分出来边界点A
先设一中间值,mid =( l+r+1)/2;
每次判断一下,这个中间值是否满足红颜色自己的性质 if(check(mid));
结果为真的话,说明A应该在中间值的右侧,即[mid,r],然后更新:l = mid;
结果为假的话,说明A应该在中间值的左侧,即[l,mid-1],然后更新:r = mid-1;

(2)二分出来边界点B
先设一下中间值,mid = (l+r)/2;
每次判断一下,这个中间值是否满足绿颜色自己的性质 if(check(mid));
结果为真的话,说明B应该在中间值的左侧,即[l,mid],然后更新:r= mid;
结果为假的话,说明B应该在中间值的右侧,即[mid+1,r],然后更新:l= mid+1;

注意

如何考虑用哪个板子,拿题先写check函数,然后想一下怎么更新区间。如果更新区间是l = mid,r = mid-1;则,中间值补上+1。

那么,为什么求A的时候需要加1,这就是会死循环中的一个。
c++里面是下取整,如果 l = r-1,mid又没有加1,那么mid = (l+r)/2 = l;
检验,当结果为真,更新,l = mid = l, l还是原来的l,[l,r]还是[l,r],死循环。

模板

while(l<r)

{

int mid=(l+r)/2;

if(q[mid]>=x)     r=mid;

else l=mid+1;

}

 

while(l<r)

{

int mid=(l+r+1)/2;

if(q[mid]<=x) l=mid;

else r=mid-1;

}

浮点二分(不考虑边界)

if()    l=mid;

else r=mid;

 

posted @ 2021-08-02 13:04  YUI唯  阅读(309)  评论(0)    收藏  举报