1. 程式人生 > 其它 >【Loj #10011. 「一本通 1.2 例 1」憤怒的牛】題解

【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; 
}