二分是一个比较大的概念,广义上把东西(可能是问题,区间等等)一分为二都是二分。

这里讲二分查找。

据说只有10%的程序员能写对二分。虽然二分是一个简单的算法。但是其变化和细节却并不简单。

整数二分:

因为mid取整的问题,如果不细心有可能会死循环。

所以写二分查找需要仔细考虑 答案在开/闭区间?mid向上/下取整?循环结束条件?这些选择的取舍不同会导致二分的写法不同,没有说必须哪一种是正确的。掌握自己喜欢的写法即可。

这里的二分保证答案必须在[L,R]闭区间,循环借宿条件为(L==R),答案下标为 L 。

代码如下,其中细节还是值得细细琢磨。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
int n,q,a[N],l,r; int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
sort(a+,a+n+); //查找满足>=q的第一个数(x或x的后继)
//因为是>=蓑衣用向下(即L)取整
//注意要保证答案在[L,R]区间,这里满足(a[mid]>=q)即mid在答案区间内r=mid,else即mid不在答案区间内l=mid+1舍弃mid
scanf("%d",&q);
l=,r=n;
while (l<r) {
int mid=l+(r-l)/;
if (a[mid]>=q) r=mid; else l=mid+;
}
cout<<a[l]; //查找满足<=q的最后一个数(x或x的前驱)
scanf("%d",&q);
l=,r=n;
while (l<r) {
int mid=l+(r+-l)/;
if (a[mid]<=q) l=mid; else r=mid-;
}
cout<<a[l]; return ;
}

浮点数二分:

因为不用考虑取整的问题,所以浮点数二分相当好些。

注意精度问题就可以了。

    double eps=1e-;
while (l+eps<r) {
double mid=(l+r)/;
if (check(mid)) l=mid; else r=mid;
}

三分求单峰函数极值:

当这个函数可能是单调函数时(极值点在端点), 三分算法无法到达端点位置, 所以要特判一下两个端点。

int lm, rm;
while(l<r)
{
lm = l+(r-l)/;
rm = lm+(r-lm)/;
if(a[lm] > a[rm]) r = rm;
else if(a[lm] == a[rm]) r=rm, l=lm;
else l = lm;
}

最新文章

  1. 用python实现逻辑回归
  2. 20 个高质量响应式的 HTML/CSS 网站模板
  3. 2014-10-28——iframe多层嵌套时获取元素总结
  4. Bootstrap简介
  5. 斐波那契(Fibonacci)数列的几种计算机解法
  6. fedora下缺少autopoint包的解决办法
  7. cocos2dx搭建开发环境
  8. WebFormJS注册位置
  9. 开源的文件比较工具:WinMerge,KDiff3,diffuse
  10. nsinteger 与 int 区别
  11. Facebook有两名重要经理离职 有一位将加入阿里
  12. Iterator——迭代接口
  13. java-9 异常处理
  14. Android中实现定时器的四种方式
  15. JavaScript 函数创建思想
  16. NC 命令引用了一个高手的文章做收藏
  17. vim 常用指令
  18. BZOJ2689 : 堡垒
  19. VS Code编辑器插件整理及配置设定
  20. php的抓取

热门文章

  1. nyoj 119: 士兵杀敌(三) 【RMQ模板】
  2. web前后端分离漏洞分析防御
  3. NIO编程模式示例
  4. MongoDB与阿里云达成战略合作,最新数据库独家上线阿里云!
  5. BZOJ 3930: [CQOI2015]选数 莫比乌斯反演 + 杜教筛
  6. 攻防世界 | string
  7. jQuery AJAX and HttpHandlers in ASP.NET
  8. JS各种变量是true或者false列表
  9. Java 内部类“覆盖&quot;
  10. DataFrame API应用案例