【题解】牛栏
题目描述
FJ新建了一个有N(2≤N≤100000)个畜栏的畜棚。畜栏的位置分布在直线的点x_1, ..., x_N(0≤x_i≤1000000000)上。
他的C(2≤C≤N)只牛不喜欢这个畜棚的设计并且对在同一个畜栏里的其他牛进行攻击。为了防止牛受到伤害,FJ想把这些牛分配到某些畜栏中,使得这些牛所在的任意两个畜栏之间的最短距离尽可能长。求最长的最短距离是多少?
输入输出格式
输入格式:
第一行,两个用空格隔开的整数,N和C;
第二至第N+1行,每行包括一个整数,畜栏的位置:X_i。
输出格式:
一行,一个整数,表示最长的最短距离。
输入输出样例
输入样例:
5 3 1 2 8 4 9
输出样例:
3
说明
样例说明:
FJ把3只牛放到位置是1、4和8的畜栏里,最短距离是3。
这道题我们不能直接用枚举做,明显用枚举会超时,那么我们可以用二分答案来优化
可以先二分一个答案,我们姑且叫它mid
然后判断,如果这个畜栏里的奶牛与其他奶牛的距离大于等于mid,就说明这个畜栏能放牛,反之则不行
再判断,如果我还有牛没放进去,那么说明我二分出来的mid值太大,就往小的找,反之则把当前mid值记录下来后,往大的找
最后输出mid的最大值就可以了。
具体程序如下:
#include<iostream> #include<algorithm> using namespace std; long long n,c,q[100005],maxx=-1,minn=1000000001; int main() { cin>>n>>c; for(int i=1;i<=n;i++) { cin>>q[i]; maxx=max(q[i],maxx); minn=min(q[i],minn); } sort(q+1,q+1+n); if(c==2) { cout<<q[n]-q[1]; return 0; } long long left=minn,right=maxx,mid,temp,ans=-1000000001,k=1; while(left<=right) { mid=(left+right)/2; temp=c; k=1; for(int i=2;i<=n&&temp!=0;i++) { if(q[i]-q[k]>=mid) { k=i; temp--; } } temp--; if(temp>0) { right=mid-1; } else { ans=max(ans,mid); left=mid+1; } } cout<<ans; }