zoukankan      html  css  js  c++  java
  • 算法描述》关于二分的两三事

      关于二分

       二分,是一种流氓算法,这种方法适用于直接算(猜、蒙、试)答案,然后直接得出最优解,

      这一方法,对于可以轻易证明答案是否可行(o(n)、o(1))的题目有奇效,

      (在NOIP2015考试的时候出了这么一道题,放倒一推蒟蒻(包括我))

      二分的使用条件

      1.如上文所说,对于轻易证明答案是否可行的题目有奇效,来一道解决一道,对于子问题有这一性质的,也可以同样用这种方法解决,奇效。(以下有相关内容)

      2.对于所查询区间值为递增或递减的问题来说,这也是一种极其可行的方法,

      关于写法以及STL若干事

      每一位神犇几乎都有自己有个性的二分写法,因为这个东西可以有所差异的地方实在太多,但究其本身,还都是同一种道理。

      1.关于<algorithm>中,STL的写法

      在c++的库函数里,有两个二分函数,分别叫upper_bound和lower_bound。

      

      upper_bound

      这一库函数的定义是:在当前传来的非降序列两个地址中间,return第一个大于当前传来的值的地址

      使用格式为:upper_bound(a+1,a+n+1,num);

      其中a数组为我们所要查询的非降数组,而1、n+1分别为我们要查找的区间地址(也即数组变量名+查询的开始 / 结束位置),num为我们所要查询的值。

      具体库函数代码如下

     1 int upper_bound(int *array, int size, int key)
     2 {
     3     int first = 0, len = size-1;
     4     int half, middle;
     5 
     6     while(len > 0){
     7         half = len >> 1;
     8         middle = first + half;
     9         if(array[middle] > key)     //中位数大于key,在包含last的左半边序列中查找。
    10             len = half;
    11         else{
    12             first = middle + 1;    //中位数小于等于key,在右半边序列中查找。
    13             len = len - half - 1;
    14         }
    15     }
    16     return first;
    17 }

      lower_bound

      这一库函数的定义是:在当前传来的非降序列两个地址间,return第一个大于等于当前传来的值的地址

      使用格式:lower_bound(a+1,a+n+1,num);

      各数组意义的定义和上面的基本一致

      库函数代码如下

     1 int lower_bound(int *array, int size, int key)
     2 {
     3     int first = 0, middle;
     4     int half, len;
     5     len = size;
     6 
     7     while(len > 0) {
     8         half = len >> 1;
     9         middle = first + half;
    10         if(array[middle] < key) {     
    11             first = middle + 1;          
    12             len = len-half-1;       //在右边子序列中查找
    13         }
    14         else
    15             len = half;            //在左边子序列(包含middle)中查找
    16     }
    17     return first;
    18 }

      2.关于个人代码习惯

      这里有两种,分别是preyW和szl两神犇的不同二分写法习惯,在这里供参考

     1 int prey_BS(int l, int r, int key)
     2 {
     3     while( l < r - 1 )
     4     {
     5         m = (l+r)>>1;
     6         if(a[m] < key)  
     7             l = m + 1;
     8         else
     9             r = m;
    10     }
    11     return l;
    12 }
     1 int zl_BS(int l, int r, int key)
     2 {
     3     int ans;
     4     while(l < = r)
     5     {
     6         m = (l + r)>>1;
     7         if(a[m] < key)
     8             l = middle + 1;
     9         else{
    10             r = m - 1;
    11             ans = r;
    12         }
    13     }
    14     return ans;
    15 }

      这两种方法可能和神犇亲手写的有出入,不过大概就是这样

      总的来说,二分还是一种解题利器,如果对于写法不够明确的看官,可以用以上的STL以及神犇写法来代替自己原本的,可能效果会更好

      然后例题就是全部openjudge以及codevs的二分题

      祝大家刷的开心

  • 相关阅读:
    应用中心无法访问时后台插件列表访问慢的优化
    HTML5 地理定位 【来自百度应用分享平台】
    快捷键补充
    进击的雨燕------------在导航上的UISearchController实现动画效果
    iOS -------- 应用程序引用系统通讯录
    字典和JSON格式字符串相互转换
    进击的雨燕--------------------Swift ? !
    Objective-C多继承的实现
    进击的雨燕------------iOS8中UIAlertController
    进击的雨燕-------------------高级运算符
  • 原文地址:https://www.cnblogs.com/PencilWang/p/5970844.html
Copyright © 2011-2022 走看看