二分答案-办公室钥匙

一条直线走廊上有n个人和k把钥匙。每个人都想去也这条线上处于位置p的办公室。要做到这一点,他们需要拿到钥匙,拿着钥匙去办公室。一旦钥匙被人拿走了,其他人就拿不到了。你要确定所有人带着钥匙到达办公室所需的最短时间。假设人们每秒钟移动一个单位距离。如果两个人同时拿到钥匙,只有一个人可以拿钥匙并且不能把钥匙给别人。

输入

第一行包含三个整数n,k和p(1≤n≤k≤2000,1≤p≤10^9),分别表示人数,钥匙数和办公地点。

第二行包含n个不同的整数a1,a2,…,an(1≤ai≤10^9),表示人的初始位置。这些位置是按任意顺序给出的。

第三行包含k个不同的整数b1,b2,…,bk(1≤bj≤10^9),表示钥匙的位置。这些位置是按任意顺序给出的。

注意,同一位置上不能有多于一个人或多于一个钥匙。一个人和一把钥匙可以定位在同一点上。

输出

输出所有的n个人带着钥匙到达办公室所需的最短时间(秒)。

输入样例 1 

2 4 50
20 100
60 10 40 80

输出样例 1

50

输入样例 2 

1 2 10
11
15 7

输出样例 2

7

样例解释:

在第一个例子中,位于20的人应该拿着位于40的钥匙,带着它去位于50的办公室。他只花了30秒。位于100的人可以拿着位于80的钥匙去办公室。他花了50秒。因此,50秒后,每个人都拿着钥匙进入办公室。

思路:将人和钥匙从小到大排序。每个人花费的时间=人与钥匙的距离+钥匙距离办公室的距离

画图可知,第一个人从第一个钥匙开始找,如果有某个钥匙拿完后时间小于mid,说明可。然后第二个人紧接上上一个人拿到钥匙的地方继续往后找钥匙。【因为前面的钥匙距离第一个人是比较近的,第一个人拿了都不满足时间,距离远的下一个人更不可能符合】,如果人数超过了n个,说明当前时间是合适的,接下来去寻找比它小的还有没有合适的了。

代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
long long n,k,p;
long long a[10000];
long long b[10000];

bool check(long long mid){
    int cnt=1;
    for(int i=1;i<=k;i++){
        if(abs(a[cnt]-b[i])+abs(p-b[i])<=mid){
            cnt++;
        }
        if(cnt>n)
            return true;
    }
    return false;
}
int main(){
    cin>>n>>k>>p;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=k;i++){
        cin>>b[i];
    }
    sort(a+1,a+1+n);
    sort(b+1,b+1+k);
    long long left=0,right=2*1000000000,ans;
    while(left<=right){
        long long mid=(left+right)/2;
        if(check(mid)){
            ans=mid;
            right=mid-1;
        }
        else{
            left=mid+1;
        }
    }
    cout<<ans;
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值