Aggressive cows POJ2456

Aggressive cows(愤怒的牛)(分治)

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 40455 Accepted: 18254

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?

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个牛棚的农舍,这些牛棚位于一条直线x1,x2,x3…xn(0<=xi<=1,000,000,000)上。他的c(2<=c<=n)头牛不喜欢这个牛棚的布局,如果把这些牛放在一个牛棚的话,它们就会变得非常愤怒,会攻击其他牛,为了防止这些牛相互攻击,农场主约翰想要把这些牛分散放在牛棚里,就像在两头牛之间尽可能大的最小距离,这个最大化的最小值是多少呢?
输入:
第1行:两个独立的数N(N个牛棚)和C (C头牛)
第2到N+1行:牛舍的位置Xi
输出:最大化的最小距离

分析

把牛舍的位置保存在数组中x[]中,排一下序。
最远的牛栏为x[0]和x[n-1];我们查找一个dis,使得以dis为最小距离时,所有的牛都能放进牛棚。
dis的范围是[1,n-1]。当然我们可以使用枚举法,但效率太低。这里我们可以使用二分搜索,用ans记录能放下所有牛的最大的dis。
首先left=x[0], right=x[n-1], dis=mid=(left+right)/2;
用这个mid去试能不能放下所有牛,如果可以,left=mid+1,更新ans=mid;
如果不可以,right=mid-1;
直到left>=right退出循环。

关键代码

	left=x[0];
	right=x[n-1];
	while(left<=right){
		mid=(left+right)/2;
		if(check(mid)){
			if(mid>ans) ans=mid;
			left=mid+1;
		}
		else{
			right=mid-1;
		}	
	}

检查mid是否符合题意

bool Judge(int dis){
	int cnt=0;
	int i;
	int start=x[0];
	cnt++;
	for(i=1;i<n;i++){
		if(x[i]-start>=dis){
			cnt++;
			start=x[i];
		}
	}
	if(cnt>=c) return true;
	else return false;
}

具体实现时可以递归实现,也可以非递归实现。
非递归代码

//非递归 
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
//定义 牛舍的数量 
int x[100001],n,c;
//判断该距离下牛能否被全部放下 
bool Judge(int dis){
	//初步定义牛舍中牛的数量以及牛的位置 
	int cnt=0,i,start=x[0];
	//已经在x【0】处放置了一头牛 start记录上一头牛的位置 
	cnt++;
	for(i=1;i<n;i++){
		//如果位置适合 放入牛 
		if(x[i]-start>=dis){
			cnt++;
			//更新start的值 
			start=x[i];
			//如果牛已经放置完了 
			if(cnt==c) 
				break;
		}
	}
	if(cnt>=c) 
		return true;
	else
		return false;
}

int main(){
	int i=0,left,right,mid;
	scanf("%d %d",&n,&c);
	for(i=0;i<n;i++)
		scanf("%d",&x[i]);	
	//对牛舍进行排序 
	sort(x,x+n);
	//二分法查找最合适的距离 
	left=x[0];
	right=x[n-1];
	while(left<=right){
		mid=(left+right)/2;
		//调用check函数 如果足够装得下这c头奶牛 说明mid小于所求解 需要更新mid
		if(Judge(mid)){
			left=mid+1;
		}
		else{
			right=mid-1;
		}	
	}
	printf("%d",right);
	return 0;
}

递归代码

//递归 
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
//定义 牛舍的数量 
int x[100001],n,c;
//判断该距离下牛能否被全部放下 
bool Judge(int dis){
	//初步定义牛舍中牛的数量以及牛的位置 
	int cnt=0,i,start=x[0];
	//已经在x[0]处放置了一头牛 start记录上一头牛的位置 
	cnt++;
	for(i=1;i<n;i++){
		//如果位置适合 放入牛 
		if(x[i]-start>=dis){
			cnt++;
			//更新start的值 
			start=x[i];
			//如果牛已经放置完了 
			if(cnt==c) 
				break;
		}
	}
	if(cnt>=c) 
		return true;
	else
		return false;
}
int Search(int left,int right){
	int mid;
	if(left>right) return right;
	mid=(left+right)/2;
	if(Judge(mid)) 
		return Search(mid+1,right);
	else 
		return Search(left,mid-1);	
}
int main(){
	int i=0,left,right,ans;
	scanf("%d %d",&n,&c);
	for(i=0;i<n;i++)
		scanf("%d",&x[i]);
	//对牛舍进行排序 ,快排的时间复杂度是O(nlogn) 
	sort(x,x+n);
	//二分法查找最合适的距离 
	left=x[0];
	right=x[n-1];
	ans=Search(left,right);
	printf("%d",ans);
	return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清木!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值