VOJ Aggressive cows
描述
Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000). His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?
Input
Line 1: Two space-separated integers: N and C
Lines 2..N+1: Line i+1 contains an integer stall location, xi
Output
Line 1: One integer: the largest minimum distance
Sample Input
5 3 1 2 8 4 9
Sample Output
3
题意
有N个房间,距离不定,往这N个房间中放C头牛,问怎么放可以使牛与牛之间的最小距离最大(前提是C头牛都放进去了)。
思路
二分查找解最小值最大问题。
查找一个mid对应为牛与牛之间距离最小值,设置二分下界为0,上届为所有房间中最大距离。
先对所有房间排序,然后从第一个房间遍历所有房间,每次查询一个房间,判断它能否塞一头牛(条件为该牛与上一头牛之间距离大于等于mid),若不能,继续查找下一个房间;若能,记下放牛个数,并刷新距离计数器为下一头牛与该牛的距离。直至遍历结束。判断放了几头牛,若个没放满,说明假设的mid太大了,需要mid=right-1;若正好放了C头牛或多放了,mid都可能还可以增大,因此先记录mid,再让mid=left-1。一路搜索,直到left>right。
注意
left+1前需要先记录mid,以免丢失正确答案。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int s[100005];
int INF=0x3ffff;
int n,c;
int minLen(int nowLen)
{
int sum=0,nowPoi=s[1];//初始化
for(int i=2;i<=n;)//第i个仓库
{
while(s[i]<nowLen+nowPoi)//while不能安排到第i个仓库
i++;//跳到下一个仓库
sum++;//计安排了几只羊的记数器+1
//cout<<"sum-"<<sum<<endl;
nowPoi=s[i];
}
return sum;
}
int main()
{
fill(s+1,s+1+n,INF);
scanf("%d %d",&n,&c);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
sort(s+1,s+1+n);
int r=s[n]-s[1],l=0,ans=0;
while(l <= r)
{
int mid=(l+r)/2;
int num=minLen(mid);
if(num>=c)
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%d\n",ans);
return 0;
}