二分的模板
找到满足某个性质的最大值
int search(int l, int r)
{
while(l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
找到满足某个性质的最小值
int search(int l, int r)
{
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
进击的奶牛
题意:把牛分别放在不同的牛棚当中,有很多种放的方法,每种方法中牛之间有一个最小距离;
题目要求的是这些方法当中最小距离的最大值。
题目要求:“相邻两头牛最小距离”的最大值
解题步骤:1、确定最小距离的范围(1 ~ 第一个牛栏到最后一个牛栏的距离)
2、二分枚举最小距离
3、检验此最小距离是否可行
4、通过检验结果确定下一次枚举范围
#include <cstdio>
#include <algorithm> //需要sort
using namespace std;
int n, m, a[100001];
bool f(int x);
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 = 1000000; //不用管初始值,能AC就是了
while (l + 1 < r) //二分
{
int mid = l + r >> 1; //二分区间
if (f(mid)) l = mid; //判断可取
else r = mid;
}
printf("%d\n", l); //l就是答案
}
bool f(int x)
{
int x1 = a[1], cnt = 1; //首先第一个隔间肯定是要放牛的.
for (int i = 2; i <= n; ++i) //循环接下来每一个隔间
if (a[i] - x1 >= x) //如果能放下
{
++cnt; //又放进了一头牛
x1 = a[i]; //更新上一头牛的位置
if (cnt == m) return 1; //循环里return
}
return 0; //无法实现
}