Aggressive cows
Description
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?
农民约翰建了一个新的牛仓,这个牛仓有N (2 <= N <= 100,000)个棚。棚沿着一条直线位于位置X1,…,XN (0 <= Xi <= 1,000,000,000)。他的C (2 <= C <= N)头牛不喜欢这种牛仓布局,一旦被关进牛栏,它们就会互相攻击。为了防止牛们相互伤害,FJ(农民约翰)希望将牛分配到牛棚中,使它们之间的最小距离尽可能大。最大的最小距离是多少?
Input
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi
*第1行 : 两个用空格分隔的整数:N和C
*第2~N+1行 : 第i+1行包含一个整数的牛棚位置Xi
Output
* Line 1: One integer: the largest minimum distance
*第1行 : 一个整数 —— 最大化的最小距离
Sample Input
5 3 1 2 8 4 9
Sample Output
3
题目摘要
N个牛棚(2,1e5]
C头牛[2,N]
在N个棚中选C个棚来安置这C头牛,使得它们之间的最小的距离最大化
以上方为案例思考一下:最近的距离<3时,牛是不是也可以被合理安置,只是不是最优的安置方式。即[1,3]为合理安置区间。 最近的距离>3时,牛棚会不够安置这些牛。即(4,1e9]为不合理区间。 所以 ans = 3。
解题思路
用二分法来找出答案。(二分范围明确)
对于N个棚,C头牛的情况下求最大化的最小值,我们就是要找到一个分界线 ans,<= ans的的最近距离为牛可以被合理安置,> ans的最近距离为牛不可以被合理安置,ans 为最大化的最小值。
那么问题转变为 如何检验判断条件 int p(int m) 的正确性?
仅一个限制:任意两个相邻牛的距离>=m, m通过二分逐渐接近并最后成为ans。
int P(int m)//构造判断条件
{
int num=0,last_position=-1e9; //last_position记录上一头牛的位置
for(int i=1;i<= N;i++)
{
if(X[i]-last_position>=m)
{
last_position=X[i]; //更新
num++; //记录可放置的数量
}
}
return num >= C;//满足要求返回1,m<=ans,执行L=mid;不满足返回0,m>ans,执行R=mid
}
上代码
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 1e6+10;
int N,C;
int X[MAXN];
int P(int m) //构造判断条件
{
int num=0,last_position=-1e9; //last_position记录上一头牛的位置
for(int i=1;i<= N;i++)
{
if(X[i]-last_position>=m)
{
last_position=X[i]; //更新
num++; //记录可放置的数量
}
}
return num >= C; //满足要求返回1,不满足返回0
}
int main()
{
scanf("%d%d",&N,&C);
for(int i=1;i<=N;i++)
{
scanf("%d",&X[i]);
}
sort(X+1,X+1+N);//有序
int L=1; //模板
int R=1e9+2;
int mid;
while(L+1!=R)
{
mid=(R+L)/2;
if(P(mid))
L=mid; //满足说明小了或刚好,再扩大看看
else
R=mid; //不满足说明太大了,缩小数据
}
printf("%d",L); //最终左侧最大的即满足条件的最大ans
}