先不说什么了,我们先看一下代码吧,注释中的内容希望对你们有所帮助
#include <iostream>
#include <stdio.h>
#include <algorithm>
#define MAX_SIZE 100000
int a[MAX_SIZE];
//n个牛棚,c头牛,而且牛棚的数量肯定是大于牛的数量的
//把n和c声明成全局变量就不用传递参数了
int n, c;
using namespace std;
bool C(int mid)
{
//cnt是用来计算放入牛棚中的牛的个数,牛是一个一个来放的。
//cnt的初始值肯定设为1,因为第一个牛棚里面肯定要放牛的啦
int cnt = 1;
int i = 1;int j=0;
//n是牛棚的数量,而不是下标,i是牛棚位置的数组的下标
while (i < n)
{
if (a[i] - a[j] >= mid)
{
cnt++;
j=i;
i++;
}
else
{
i++;
}
//当cnt==c的时候这个时候就表明牛已经放完了,所以就可以直接结束这个函数了
if (cnt>=c) return true;
}
return false;
}
int main()
{
while (cin>>n>>c)
{
for (int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
//排序完值后就要进行从0 到 a数组中最大的一个数开始计算了,因为其答案肯定在[0,max(a)]里面
int low =0,high=a[n-1];
int mid;
//这个while循环结束之后,low和high的值肯定是相差1的
while (high-low>1)
{
mid=(low+high)/2;
if (C(mid)) low=mid;
else high=mid;
}
//我们这里利用的是最小值最大化,low<high,并且low和high只能有一个是我们需要求的结果
//如果high是对的化,那么比它小的low肯定也可以,因此答案是low(左边的数)
cout<<low<<endl;
}
return 0;
}
/*
text data:
5 3
1
2
8
4
9
*/
重要模型:
这个算法除了在有序数列查找值外,在求最优解的问题上非常有用。
若有一个“求满足某个条件C(x)的最小的x”问题,如果所有的x’>=x也满足C(x’)的话,就可以用二分查找来解决。首先我们将区间的左端点初始化为不满足C(x)的值,右端点初始化为满足C(x)的值。然后每次取中点mid=(low+high)/2,判断C(mid)是否满足并缩小范围,直到[low,high)足够小了为止。最后low就是要求的最小值。