题目戳这里
题目描述 Description
yh拥有一条街道,街道上共有n间房子,每间房子的坐标为xi(yh的房子比较神奇,可能重叠)。
同时,yh有m个女朋友(这是事实),yh打算给每位女朋友分配一间房子。两个女朋友间的距离相隔越近,她们之间产生冲突的可能就越高。yh想尽可能的减小女朋友间的冲突,于是他打算让他的女朋友间的最小距离最大,你能帮yh找出这个最大值吗?
输入描述 Input Description
第一行两个整数,n,m,表示yh有n间房子,有m个女朋友
第二行为n个整数,xi,表示各间房子的坐标。
输出描述 Output Description
输出1行,表示yh女朋友间的最小距离的最大值
样例输入 Sample Input
5 3
1 2 8 4 9
样例输出 Sample Output
3
刷了好久的二分…………
这道题是一道二分裸题,使得女朋友们(绝对是大于0小于等于2(手动斜眼))之间的距离最小值最大
什么是二分呢
其实很简单的就一句话:二分答案+验证
对于一个可行解来说,从1开始无限枚举总会得到的,但是这样实在是太慢
那么,假如说一个题中1~100000都是不行的,200000~∞都是不行的,那么这一部分应该也就没有枚举的必要了
推广一下,只要答案满足单调性,那么只需要枚举一个上界和一个下界,再验证答案是不是在这个区间内即可
这样的话,O(不知道有多大)的复杂度就可以简化为O(logn)
因此
二分女朋友之间的距离,之后在判断能否在这个范围内成立就可以了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
int xl[1245000];
int n,m;
bool check(int mid){
int last=1;
int cnt=m-1;
for(int i=1;i<m;i++){
int now=last+1;
while(now<=n&&xl[now]-xl[last]<mid){
now++;
}
if(now<=n){
last=now;
cnt--;
}
}
if(cnt>0){
return false;
}
return true;
}
int div(){
int down=1,up=847483647;
while(down+1<up){
int mid=(up+down)/2;
if(!check(mid)) up=mid;
else
down=mid;
}
return down;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d",&xl[i]);
}
sort(xl+1,xl+1+n);
cout<<div()<<endl;
return 0;
}
其实这道题是挑战程序设计里面的原题= =