详解二分算法
Powered by WSY in SSF
2019-11-02 14:23:05
【1】定义
二分算法,顾名思义,就是把一个数列或数组分一下,分成两段。那么究竟什么情况下比较适合使用二分算法,二分算法能用于哪些领域呢?
先来举一个例子:
(奥数)你有10枚古罗马硬币,但是有一枚被一个小偷给掉包了(假硬币要更轻一些),于是你把这些硬币送到当地的警察局(局长超级Lazy),他们只是告诉你那枚假硬币上面有小偷的指纹,而且你只有一个天平,那么你最少需要称几次,才能找出那枚假硬币的呢?
解:4次
相信通过这道奥数题大家已经无形中运用到了二分的算法。但是值得注意的是,二分查找只能用于有序数列
【2】比较次数
int r=0;//右边的变量
int l=n-1;//左边的变量
while(r<l)//满足条件时进入循环
{
int mid=(r+l)/2;//二分查找的精华所在:mid变量用来得到每次二分后的位置
if (a[mid]==ans) return mid;//如果成功就结束了
else if(a[mid]>ans) r--;//否则调整
else l++;
}
例题:
农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi<= 1,000,000,000). 但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?
源码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3;
int n,m,x[N];
inline bool check(int d)
{
int cow=1;
int rgt=x[1]+d; for(int i=2;i<=n;++i) { if(x[i]<rgt) continue; ++cow; rgt=x[i]+d; } return cow>=m; } int main() { cin>>n>>m; for(int i=1;i<=n;++i) cin>>x[i]; std::sort(x+1,x+n+1); int l=0,r=x[n]-x[1]; while(l<=r) { int mid=l+r>>1; if(check(mid)) l=mid+1; else r=mid-1; } cout<<r<<endl; return 0; }
本文结束,望大家多多支持!