题目
农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,…,xN (0 <= xi <= 1,000,000,000). 但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?
解题思路
有最小距离i,j,k (i<j<k) 如果i满足题目条件,那么j可能满足题目条件也可能不满足题目条件(如果j情况下牛不能全部放下)。如果在j的情况下牛不能全部放下,则在k的情况下牛也不能全部放下。因此可以用二分法来二分最小距离。
二分判断?
将奶牛从第一个隔间开始放就ok了(这样放能使放入牛数最大化)
此时二分最小距离为s,每次取距离上一次放牛的隔间大于等于s,且距离的上次放牛隔间的最短(为了使牛数最大化)。判断一下是否能全部放完即可判断该方案是否可行。
#include <cstdio>
#include <algorithm>
using namespace std;
int n,k,ans;
int a[101010];
bool check(int mid)
{
int L=1,R=2;
int num=1;
while (true)
{
while (a[R]-a[L]<mid && R+1<=n) R++;
if (a[R]-a[L]>=mid) num++;
if (num==k) return true;
L=R;
R++;
if (R>n) return false;
}
}
int main()
{
freopen("i.in","r",stdin);
freopen("i.out","w",stdout);
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
int l=0,r=a[n];
a[n+1]=2100000000;
while (l<=r)
{
int mid=(l+r)/2;
if (check(mid))
{
l=mid+1;
ans=mid;
}
else r=mid-1;
}
printf("%d\n",ans);
}