二分的初步= =

题目戳这里
题目描述 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;
}

其实这道题是挑战程序设计里面的原题= =

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值