007:Aggressive cows
总时间限制: 1000ms 内存限制: 65536kB
描述
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?
输入
-
Line 1: Two space-separated integers: N and C
-
Lines 2…N+1: Line i+1 contains an integer stall location, xi
输出
- Line 1: One integer: the largest minimum distance
样例输入
5 3
1
2
8
4
9
样例输出
3
提示
OUTPUT DETAILS:
FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.
Huge input data,scanf is recommended.
思路:
主要思想就是二分法,二分法的实现是不断取中间值进行比较,然后重新设置left或者right的值,最后得出解的过程。
本题的要点是,对于输入数据进行排序后,得到最大的D=(ar[N-1]-ar[0])/C+1,加1是防止除法省略一位;
然后是left=1(至少为1),r=D,求mid=left+(right-left)/2;
然后利用mid去不断比较;
比较过程的想法是:选x0是最小的位置,然后写一个寻找最近位置且比x0大于等于D的位置,若找到计数器就+1,找不到时返回-1同时寻找过程退出,然后对于计数器的条件进行比较,如果小于C,说明mid太大,设置right=mid-1;否则mid较小,可能继续增加,保存此时的mid,并设置l=mid+1;最终得到结果。
代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/*
找到离xi最近且比xi+1大于等于距离D的位置,因为最终的最大的D就是xi和xi+1保持“最近”了(如果还能容纳其他位置,那就不叫最大的最小了)
*/
int find_near(const int *p,int D,int i,int N) {
int tmp = p[i++] + D;
for (i; i < N; ++i)
if (p[i] >= tmp)
return i;
return -1;
}
int process(const int N,const int C) {
int *ar = new int[N];
for (int i = 0; i < N; ++i)
scanf("%d", &ar[i]);
sort(ar, ar + N);
//left,right,mid
int D = (ar[N - 1] - ar[0]) / C + 1;
int l = 1, r = D;
int max_d = l;
while (l <= r) {
//记得重置mid
int mid = l + (r - l) / 2;
int cnt = 1;
for (int i = 0; i < N;) {
int j = find_near(ar, mid, i, N);
if (-1 != j) {
cnt++;
i = j;
} else
break;
}
if (cnt >= C) {
max_d = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
delete[] ar;
//最大
return max_d;
}
int main() {
int N, C;
scanf("%d %d", &N, &C);
printf("%d", process(N, C));
return 0;
}