Codeforces 830A, Binary Search

来源:互联网 发布:无忧seo 编辑:程序博客网 时间:2024/06/17 11:52

题意

简单并抽象的说,现在有一根直线,上面某个坐标 p 标记了办公室所在的位置,同时有 n 个坐标标记了 n 个人的位置,以及 k 个标记了钥匙的位置。现在这 n 个人都想进入这个办公室,但是进入的前提是需要有钥匙,但每个人只能有一把钥匙,所以如果某个人的位置没有钥匙的话,他需要走到某个有钥匙的位置拿到以后进入办公室。所有的人可以同时行动,数量上满足如下关系:1n103nk20001p109。假设每个人移动一个坐标单位耗时为1,请计算最小耗时是多少?(输入过程中,所有的点坐标都是乱序的)

Solution

这样想,因为钥匙的数量总是够的,假设人在的点是 personPosi,钥匙在的点是 keyPosj,那么人拿到钥匙同时进入办公室的时间可以描述为:

ti=|personPosikeyPosj|+|keyPosjp|

考虑 n 个人同时行动,那么耗时应当是:

cost(personPos,keyPos)=max{ti|i=1n}

容易知道这个函数的取值范围是:[0,2×109]。最小化目标函数,那么可将问题转化为求解 ti 的最小值。先把钥匙和人的位置按照从小到大的顺序排列(天然的操作,不要问为什么),但是问题在于不知道具体要选择哪个点,虽然我们凭直觉知道需要选择附近的某个点,那么不妨遍历一遍找到合适的那个点,因为目前问题的规模不算大。假设当前允许的最大耗时为 T,那么

i:=1
Foreach j:=1k {
    if tiT {
        i++
        if i>n:break
    }
}

这一部分的复杂度为 O(k),因为知道耗时的取值范围,那么可以通过二分搜索来找到合适的 T,那么该解法的复杂度为O(klogn)。代码如下:

#include <iostream>#include <cstdlib>#include <cstdio>#include <algorithm>using namespace std;const long long int maxn = 2e9 + 5;long long int personPos[1002];long long int keyPos[2002];long long int n, k, p;bool judge(long long int t) {    int j = 1;    for (int i = 1; i <= k; i++) {        if (abs(personPos[j] - keyPos[i]) + abs(p - keyPos[i]) <= t) {            j++;            if (j > n) return true;        }    }    return false;}void solve() {    long long l = 0, r = maxn, mid = 0, ans = 0;    while (l <= r) {        mid = (l + r) >> 1;        if (judge(mid)) {            ans = mid;            r = mid - 1;        } else l = mid + 1;    }    cout << ans << endl;}int main() {    scanf("%I64d %I64d %I64d", &n, &k, &p);    for (int i = 1; i <= n; i++) {        scanf("%I64d", personPos + i);    }    for (int i = 1; i <= k; i++) {        scanf("%I64d", keyPos + i);    }    sort(personPos + 1, personPos + n + 1);    sort(keyPos + 1, keyPos + k + 1);    solve();    return 0;}

还有一种方法可以通过动态规划来做,但复杂度比这个高,为O(kn),这里就不写了,其实道理差不多。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 晚修自己老喜欢讲话怎么办 宝2岁宝脾气大怎么办 宝宝比同龄孩子发育晚怎么办 早教机构业绩不好怎么办 孩子上早教课哭怎么办 两岁宝宝哭闹不止怎么办 7个月宝宝怕生疏怎么办 5个月宝宝怕洗澡怎么办 4个月宝宝认人怎么办 2岁宝宝语言迟缓怎么办 宝宝老是哭闹不睡觉怎么办 7岁儿童说话晚怎么办 一岁多的婴儿说话晚该怎么办 宝宝甲低300多怎么办 两岁半宝宝还不怎么会讲话怎么办 宝宝两岁半了还不讲话怎么办 两岁宝宝怕生人怎么办 四岁宝宝不说话怎么办 1岁宝宝牙齿黄斑怎么办 儿子俩周半了就是不说话怎么办 两岁宝宝牙齿上有黑渍怎么办 两岁宝宝牙齿发黑怎么办 求帮助宝宝刷牙不会漱口怎么办 牙膏不小心吞了怎么办 宝宝误吃了牙膏怎么办 宝宝吃了30g牙膏怎么办 孩子把牙膏吞了怎么办 二岁宝宝有蛀牙怎么办 3岁宝宝有蛀牙了怎么办 三岁宝宝夜惊怎么办 小班孩子跳舞不好好跳怎么办 15个月宝宝拉稀怎么办 孩子学习不认真该怎么办 孩子学习不自觉该怎么办 孩子学习压力大该怎么办 分手发信息不回怎么办 两岁宝宝不会回答问题怎么办 分手了我还想他怎么办 两岁宝宝特别不听话怎么办 2岁宝宝争东西怎么办 两岁宝宝钙吸收不好怎么办