码迷,mamicode.com
首页 > 其他好文 > 详细

模板 - 二分

时间:2019-01-25 14:10:02      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:else   整数   check   lse   疑问   模板   验证   while   pre   

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

首先约定二分的区间为[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,这时还是根据自己要求的是较大还是较小特判一下退出最好。

模板 - 二分

标签:else   整数   check   lse   疑问   模板   验证   while   pre   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!