二分答案思路:这个牛栏的思路就是二分答案,因为他要我们求最大的最近距离,我们可以用二分答案来进行试探,如果在当前二分答案的条件下,牛进栏的数量没有达到要求,说明我们二分的距离太大了,导致很多牛都不符合进去的条件,我们将r指针移到mid-1的位置缩小一些二分答案的范围就可以了,如果牛进栏的数量超过或者等于规定的数量,我们把二分答案开的再稍微大一点,来找到一个最大的数,这个数可以放下规定的牛,并且又在l+1的推动下,他是最大的并且在临界点的。
上代码
#include<bits/stdc++.h>
using namespace std;
int n,c,ans;
int a[100010];
bool check(int x){
int m=1,now=1; //设置两个位置,第一个位置肯定要放牛的,所以m=1,然后now指向第一个牛栏,从第二个开始
for(int i=2;i<=n;i++){
if(a[i]-a[now]>=x){
m++,now=i;
//如果当前牛栏和上一头牛的距离大于我们设置的最大距离,我们就将牛放进来,并且将now赋值给这个牛栏,下一次判断牛栏的时候就会查找下一头牛和这个牛栏的距离
} //不满足的直接i++跳过了这个牛栏
}
if(m<c)return false;
//最后判断牛栏数是不是得到了题目要求的那么多,如果没有的话说明这个距离还是开大了
//导致很多牛都没有进牛栏,我们将r指针移动到mid-1的位置
else return true;
//否则牛栏就放下了,因为放的牛可能回超过,我们就向右继续试探如果加大一点距离的话会不会导致牛栏放不下
//最后的放下的临界点就是我们的最大的最近距离
}
int main(){
cin>>n>>c;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
int l=1,r=a[n],mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid))l=(ans=mid)+1;
else r=mid-1;
// cout<<l<<" "<<r<<" "<<mid<<endl;
}
cout<<ans;
return 0;
}