zoukankan      html  css  js  c++  java
  • 整数二分的正确打开方式

    参考: 算法竞赛 , 这篇$Blog$

    感觉二分一直迷迷糊糊,终于要来写一篇小结辣

     总的来说有两种写法:

      1.记录答案

      2.不记录答案

     细分有三种:

      1.记录答案(左右边界哪个是答案都差不多)

      2.不记录答案且找最小的合法解

      3.不记录答案且找最大的合法解(最易错的!!)

    下面就来具体说说细分的三种

     1.记录答案

    //找到最大的合法解

    while
    (l<=r) { int mid=(l+r)>>1; if(check(mid))ans=mid,l=mid+1; else r=mid-1; } printf("%d ",ans);
    //找到最小的合法解

    while
    (l<=r) { int mid=(l+r)>>1; if(check(mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d ",ans);

     2.不记录答案且找最小的合法解

    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    printf("%d
    ",l);

     3.不记录答案且找最大的合法解

    $Attention!$这里一定是$mid=(l+r+1)>>1$

    考虑这样一种情况:$r=l+1,mid=(l+r)>>1=l$,$l$合法,$l=mid=l$,于是陷入死循环

    while(l<r)
    {
        int mid=(l+r+1)>>1; //!Attention!
        if(check(mid))l=mid;
        else r=mid-1;
    }
    printf("%d
    ",l);

    注意点与拓展

    1.不同的形式采取相应的$mid$取法

    2.采取$>>1$而不是$/2$.这是因为右移运算是向下取整,而整数除法是向$0$取整,在二分值域包含负数时出错.

    3.(对于后面两种做法而言)处理二分中的无解情况: 把最初的二分区间$[1,n]$扩展成$[0,n+1]$,如果二分终止后停留在扩展结点上则无解

    讲了这么多我觉得还是第一种做法最好了,考虑的要少很多: )

    但是算法竞赛上就第一种没讲???

    光伴随的阴影
  • 相关阅读:
    筛选IPV4地址
    linux查看磁盘空间大小df du fdisk stat命令
    编写shell脚本sum求1100累加和
    postman通过Cookies登录博客园
    Linux中mount挂载命令简洁使用方法
    linux如何查询文件及文件夹大小
    postman接口测试中添加不同的断言
    设计模式之状态模式
    Docker安装SQL Server
    架构漫谈读书笔记
  • 原文地址:https://www.cnblogs.com/forward777/p/11274599.html
Copyright © 2011-2022 走看看