【Loj #10011. 「一本通 1.2 例 1」愤怒的牛】题解

题目链接

题目

农夫约翰建造了一座有 间牛舍的小屋,牛舍排在一条直线上,第 间牛舍在 的位置,但是约翰的

头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。

牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?农夫约翰建造了一座有 间牛舍的小屋,牛舍排在一条直线上,第 间牛舍在 的位置,但是约翰的

头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。

牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?

思路

首先我们对牛棚从小到大排序。

然后我们二分距离,再暴力检查是否可行。

时间复杂度:\(O(n\log n)\)

Code

// Problem: #10011. 「一本通 1.2 例 1」愤怒的牛
// Contest: LibreOJ
// URL: https://loj.ac/p/10011
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
//#define N
int n, m, i, j, k; 
int a[100010]; 
int l, r, mid, now; 

int check(int d)
{
	for(i=2, j=1, now=a[1]; i<=n; ++i)
		if(a[i]-now>=d) ++j, now=a[i]; 
	return j>=m; 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); 
	for(i=1; i<=n; ++i) a[i]=read(); 
	sort(a+1, a+n+1); 
	l=0, r=a[n]; 
	while(l<r)
	{
		mid=(l+r+1)>>1; 
		if(check(mid)) l=mid; 
		else r=mid-1; 
	}
	printf("%lld", l);  
	return 0; 
}

posted @ 2021-12-09 21:32  zhangtingxi  阅读(213)  评论(0编辑  收藏  举报