zoukankan      html  css  js  c++  java
  • 模板

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

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

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

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    
    //找大于等于n的最小的m
    bool ok(int m){
        return m>=n;
    }
    
    int main(){
        while(~scanf("%d",&n)){
            int l=1,r=1000000,m,ans;
            while(1){
                m=(l+r)>>1;
                printf("%d
    ",m);
                if(m==l){
                    //边界情况
                    if(ok(l)){
                        //假设要求最小值,要先判断l
                        ans=l;
                    }
                    else if(ok(r)){
                        //l不行再判断r,不能直接返回,因为不能确定答案是l或r其中之一
                        ans=r;
                    }
                    else{
                        ans=-1;
                    }
                    break;
                }
                if(ok(m)){
                    //假设要求最小值,m满足条件则去找更小的
                    r=m;
                }
                else{
                    //m不满足条件,排除掉
                    l=m+1;
                }
            }
            printf("ans=%d
    ",ans);
        }
    }

    之前为什么会觉得边界条件是 $l$ 和 $r$ 相差为1,其实边界条件是 $l$ 和 $r$ 重合。其上一步的条件是 $l$ 与 $m$ 重合而 $l$ 和 $r$ 相差为1,此时若 $m$ 满足条件则 $r=m$ 收缩至 $l$ ,否则 $l=m+1$ 扩大至 $r$ 。所以这才是正确的写法。但是上面这样写完全足够了。下面是假设答案一定存在在 $[l,r]$ 中任意一个整数中。

    #include<bits/stdc++.h>
    using namespace std;
    
    int n;
    
    //找大于等于n的最小的m
    bool ok(int m){
        return m>=n;
    }
    
    int main(){
        while(~scanf("%d",&n)){
            int l=1,r=1000000,m;
            while(l<r){
                m=(l+r)>>1;
                printf("%d
    ",m);
                if(ok(m)){
                    //假设要求最小值,m满足条件则去找更小的
                    r=m;
                }
                else{
                    //m不满足条件,排除掉
                    l=m+1;
                }
            }
            printf("ans=%d
    ",l);
        }
    }
  • 相关阅读:
    Oracle 10g 改机器名后监听不能启动 解决方案 TNS12541 TNS12545
    14.3.1 IMPDP 命令行选项
    14.3.2 调用IMPDP —— 导入表空间
    三十岁之前不必在乎的事
    正则表达式
    GridLayout and GridData
    非UI线程更新界面
    整理用Java实现数字转化成字符串左边自动补零方法
    stackLayout
    读写properties文件
  • 原文地址:https://www.cnblogs.com/Yinku/p/10319223.html
Copyright © 2011-2022 走看看