一、适用范围
二分算法的基本用途是在单调序列或单调函数中做查找操作,因此问题的答案具有单调性的时候,我们就可以通过二分把求解转换为判定。
二分算法的思想是不断将待求解区间平均分成两份,根据求解区间中点的情况来确定目标元素所在的区间,这样就把解的范围缩小一半。
二、代码实现
1、整数二分:
int erfen(int l,int r) { int ans; while(l<=r){ int mid = (l+r)>>1; if(check(mid)){//判断一下是否满足条件 ans = mid; l = mid + 1; } else r = mid - 1; } return ans; }
2、实数二分
double erfen(double l,double r) { double mid; while(fabs(l-r)>0.01){//0.01是题目中精度要求, mid = (l+r)/2.0;//浮点型数据作比较要注意其精度问题 if(check(mid)) r = mid; else l = mid; } return l; }
三、例题
愤怒的牛
题目描述
农夫约翰建造了一座有 间牛舍的小屋,牛舍排在一条直线上,第 间牛舍在 的位置,但是约翰的 头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。
牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?
输入格式
第一行用空格分隔的两个整数 和 ;
第二行为 个用空格隔开的整数,表示位置 。
输出格式
输出仅一个整数,表示最大的最小距离值。
样例
样例输入
5 3 1 2 8 4 9
样例输出
3
做题思路:
题目要求寻找最小的间隔距离,类似求最值问题,二分可以很好的解决。
1、对牛舍的位置x进行排序
2、将第一头牛放进第一间牛舍
3、运用二分的方法去判断一个距离,每个求出的值,都需要去验证是否满足条件,直到二分算法结束,得出最佳距离。
AC代码:
#include<bits/stdc++.h> using namespace std; int a[100005]; int n,m; int check(int d)//判断一下此间隔是否适用 { int sign = d+a[1]; int sum = 1; for(int i=2;i<=n;i++){ if(a[i]<sign) continue; sign = a[i]+d; sum++; } return sum>=m; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1);//必须排序,二分查找要求是单调序列 int l=0,r=a[n]-a[1],mid; while(l<=r){//二分查找最小的间隔 mid = (r+l)>>1; if(check(mid)) l = mid+1; else r = mid-1; } printf("%d ",r); return 0; }
一天终将过去,你能留下什么。