疯牛

疯牛

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述
农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000).
但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?
输入
有多组测试数据,以EOF结束。
第一行:空格分隔的两个整数N和C
第二行——第N+1行:分别指出了xi的位置
输出
每组测试数据输出一个整数,满足题意的最大的最小值,注意换行。

样例输入

5  3

1

2

8

4

9

样例输出

3


此题重要的是弄清楚思路:保证两两头牛之间的最小距离最大。此题我们最开始想到的会是穷举法,但是此方法效率不可避免的很低,所以为了提高效率,这里可以引入二分法。二分法可以使答案区间依次减少,而由此减少计算的次数。

方法是 首先把输入进去的房间号码排序,找出最大号与最小号,相减就是可能的最大的最小距离。然后左端点是1 组成:(1,a[m-1]-a[0])一个区间 然后取中点 带入数据测试,看有多少个区间可以满足这个距离,当满足的区间数大于等于牛的数量减一 那这个数就可以满足 则正确最合适的答案在区间的右半段 否则在左半段 依次计算 即可解决 。

下边的代码仅供参考

#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a,const void *b);
int a[1000000];
int main()
{
int m,n;
while(scanf("%d %d",&m,&n)!=EOF)
{
int i,j,k;
int x,y,z;
int num;
for(i=0;i<m;i++)
{
scanf("%d",&a[i]);
}
qsort(a,m,sizeof(a[0]),cmp);
if(n==2)//特殊情况 如果只有两头牛 只需要 最大房间号码减去最小房间号码
printf("%d",a[m-1]-a[0]);
else
{
x=1;//左端点
y=a[m-1]-a[0];//右端点
while(y-x>1)
{
z=(x+y)/2;
j=0;//需要计算距离的左坐标
k=1;//右坐标
num=1;//计满足距离的个数
for(i=1;i<m;i++)
{
if(a[k]-a[j]>=z)//如果满足距离 计数值加一 j取代k的位置 k位置往前移一
{
num++;
j=k;
k=k+1;
}
else //不满足 只需要k的位置 往前移一
k++;
}
// printf("%d*\n",z);
if(num>=n)
{
x=z;
// printf("%d\n",b[l-1]);
}
else
{
y=z;
}
}
printf("%d\n",x);
}
}
return 0;
}


int cmp(const void*a,const void*b)
{
return *(int *)a - *(int *)b;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值