Poj 2456 Aggressive cows :【题解】

Problem Descrip

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

Hint

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.

上午一直觉得对目前我来说已经是一道难题了,想通了之后发现倒还可以。题目大意是在一条数轴上的N个点内找到能放下C头牛的点中距离的最大值。例如1、2、4、8、9这几个点,距离最大只能是8(1—9),但这样只有一个间隔、只能放下2头牛。check函数利用贪心算法,判断传入的len值能否满足:在a[end] - a[start] >= len的条件下count >= c-1(为什么是c-1呢,比如有3头牛,只需要有2个len长度的间距就可以),可以则传回true,否则传回false。
在主函数中的二分法中,当传回true,说明mid这个间隔可以放下,那在右区间继续在寻找mid值;当传回false,说明mid不能放下(所有点不满足此情况下的mid),则转向左区间,缩小mid值。
感谢学长的亲自指点和coding呀!

AC代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5+10;  // const要加上 
int n, c;
int a[maxn];
bool check(int len){			// len是传进来的暂定距离 
	int start = 0, end = 1, count = 0;
	while(end < n){
		if(a[end] - a[start] >= len){
			count ++;
			start = end;
		}
		else{
			end ++;
		}
	}
	if(count >= c-1)	return true;
	else	return false;
	
}
int main(){
	int l = 0, r = 0, res = 0;
	scanf("%d %d", &n, &c);
	for(int i=0; i < n; i++)
		scanf("%d",a+i);
	sort(a, a+n);
	l = 1;
	r = a[n-1];					// 直接给l和r边界值 
	while(l <= r){
		int mid = (l + r) >> 1;
		if(check(mid)){				// 如果满足条件,即此时mid(奶牛的距离)值可以放下 
			l = mid + 1;			// 那么继续增大mid(距离)值,让left向右移动,找到最不拥挤的距离 
			res = mid;
		}
		else
		r = mid - 1;
	}
	printf("%d\n",res);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值