https://ac.nowcoder.com/acm/contest/951/A
题目描述
农夫约翰建造了一座有n间牛舍的小屋,牛舍排在一条直线上,第i间牛舍在xix_ixi的位置,但是约翰的m头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。
牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?
输入描述:
第一行用空格分隔的两个整数n和m;
第二行为n个用空格隔开的整数,表示位置 xix_ixi
输出描述:
输出仅一个整数,表示最大的最小距离值。输入
5 3 1 2 8 4 9输出
3说明
把牛放在1,4,8这样最小距离是3 。
二分和三分的详解:https://www.cnblogs.com/zzh666/p/9418071.html
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
ll x[100001];
ll a[100001];
ll n,m;
//最关键的部分check
bool check(ll X){
ll bef=x[0],total=1;//从第一个牛开始遍历,第一头牛被安排下total=1;
ll i;
for(i=1;i<n;i++){
if(x[i]-bef>=X){//大于距离X,符合条件
total++;//安排下一只牛
bef=x[i];//记录新安排下的牛的位置
}
if(total>=m)return true;//提前安排好m个牛肯定满足条件
}
return false;
}
int main(){
scanf("%lld %lld",&n,&m);
for(int i=0;i<n;i++){
scanf("%lld",x+i);
}
sort(x,x+n);
ll minn=0x3f3f3f3f;
//求最小的距离
for(ll i=1;i<n;i++){
minn=min(x[i]-x[i-1],minn);
}
ll l=minn,r=x[n-1]-x[0];//求最大的二分范围
//二分模板
while(l<=r){
ll mid=(l+r)>>1;
if(check(mid))l=mid+1;
else r=mid-1;
}
cout<<r<<endl;
//不明白一个地方:求出来的r一定就能符合给定的数组的安排吗
return 0;
}