首页 > 其他 > 详细

模板 - 二分

时间:2019-01-25 14:03:47      阅读:198      评论:0      收藏:0      [点我收藏+]

之前一直都没有想清楚整数的二分到底是要打算怎么搞。

首先约定二分的区间为[l,r]闭区间。

看一下下面这个实现,由于我们的约定,所以l与r都要取能取到的(合法的)值。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    while(~scanf("%d",&n)){
        int l=1,r=1000000;
        int m;
        while(l<r){
            m=(l+r)>>1;
            printf("%d\n",m);
            if(m<n){
                l=m+1;
            }
            else{
                r=m;
            }
        }
        printf("ans=%d\n",l);
    }
}

由于我们约定是在[l,r]闭区间去找的,所以当中间点m<n的时候,认为中间点过小,把l改成m+1(因为m也取不到),反之把r改成m。

那么毫无疑问最后的一次操作中l与r的距离恰好是1。此时我们取得的m恰好为l,验证m小之后把l改成m+1也就是r,反之则答案就是l。所以上述的写法是正确的。

总结:整数的二分,闭区间[l,r],while(l<r),判断的是必须是<符,答案是l。

 

那么假如我们是用check(m)呢,也就是说询问m是否符合要求?这东西情况就复杂多了,根据你要找的值是最大还是最小感觉还不一样。我们可以实现查找在区间中等于n的第一个或者最后一个。

依然约定是闭区间[l,r],while(l<r),仿照上面对l与r进行收缩,最终会使l与r相差恰好为1,这时还是根据自己要求的是较大还是较小特判一下退出最好。

模板 - 二分

原文:https://www.cnblogs.com/Yinku/p/10319223.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!