POJ2456(复赛模拟试题) 好斗的奶牛 解题报告

【问题描述】  
  
  John拥有一个的属于自己的农场。最近,为了提高农场的运营状况,他建了一个有N 个槽的畜棚。这些槽位于一条直线上,其座标分别为x1,x2,…xN(0≤xi≤1,000,000,000)。


  John新购买了一批奶牛,数量为C头。这些奶牛不喜欢槽式生活,并且经常进行一些激烈的打斗。为了减少奶牛们相互伤害而造成的损失,John必须按一定的策略来来安排这些奶牛进入槽。John策略就是,使距离最近的两头奶牛间的距离越大越好。 


  设D为距离最近的两头奶牛间的距离,请帮住John求出最大的D。 
 
    
 【输入格式】  
  
  第1行2个数N和C(2<=C<=N)。
  接下来N行,每行一个数表示第i个槽的位置xi。


 
    
 【输出格式】  
   
  距离最近两头奶牛间的距离的最大值。
 
    
 【输入样例】   
   
5 3
1
2
8
4
9


 
    
 【输出样例】  
   
3
 
    
 【样例解释】  
   
John将他的3头奶牛放入座标为1、4、9这3个槽类,最近的两头奶牛间的距离为3.
 
    
 【数据范围】  
   
50%数据保证n<=100
70%数据保证n<=10000
100%数据保证n<=100000
 
    
 【来源】  
  
POJ 2456


解题思路:根据题意,要求最小值最大,自然想到二分猜答案,我们可以猜最近两头奶牛间距离的最大值,每猜一个距离,进行判断,如果答案可行,则猜的距离可以再大些,如果答案不可行,则猜的距离就要再小些。在判断答案是否可行时,可以用cnt来记录匹配到槽的奶牛数,先将第一头奶牛放在第一个槽,然后依次枚举每个槽,当枚举的槽与前一个放奶牛的槽的距离大于等于猜的答案时,cnt加1,最后判断cnt是否大于等于奶牛数即可。


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;
int N,C;
int x[maxn];
bool check(int m)  //判断答案是否可行
{
	int cnt=1,k=1;  //用cnt记录匹配到槽的奶牛数,k记录上一个匹配到奶牛的槽的编号
	for(int i=2;i<=N;i++)
	if(x[i]-x[k]>=m)
	{
		cnt++;
		k=i;
	}
	if(cnt>=C)  return 1;
	else  return 0;
}
int main()
{
	freopen("48.in","r",stdin);
	//freopen("48.out","w",stdout);
	scanf("%d%d",&N,&C);
	for(int i=1;i<=N;i++)
	scanf("%d",&x[i]);
	sort(x+1,x+1+N);
	int A=0,B=1000000000,ans=0;
	for(int i=0;i<35;i++)  //二分猜答案
	{
		int m=(A+B)/2;
		if(check(m))  ans=m,A=m+1;
		else  B=m-1;
	}
	printf("%d\n",ans);
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章