题解:AT_joi2009ho_b ピザ

songhongying

2024-11-18 20:02:22

Solution

题目传送门

解题思路:

方法一:直接暴力枚举每个人顺时针最近的与逆时针最近的作比较,每次加上最近的一个(即第一个大于等于这个人的位置的位置),但效率属实有点低,会超时。

方法二:依旧是枚举每个人,但如果每次都从头开始找位置的话,就太慢了,所以我们可以使用一种高效的查找方法:二分查找。这样就可以快速求出顺时针的情况下第一个大于等于这个人的位置的位置了。然后我们可以知道逆时针的最优位置,应为第一个小于这个人的位置的位置,也就是顺时针的最优位置的前一个位置。最后,再将这两个位置与当前位置的距离求最小值,累加起来即可。

还有一个点要注意:就是二分查找时必须保证数列有序,但题目中未保证有序,所以我们应该手动给数组排个序。

Code:

#include<bits/stdc++.h>
using namespace std;
int a, n, m, d[100005], k[10005], t;
int main() {

    scanf("%d%d%d", &a, &n, &m);
    for (int i = 1; i < n; i++) {
        scanf("%d", &d[i]);
    }
    d[n] = a;
    sort(d + 1, d + n);
    for (int i = 1; i <= m; i++) {
        scanf("%d", &k[i]);
        int left = 0, right = n;
        while (left + 1 < right) {
            int mid = (left + right) / 2;
            if (d[mid] <= k[i])  left = mid;
            else  right = mid;
        }
        t += min(d[right] - k[i], k[i] - d[right - 1]);
    }
    printf("%d\n", t);

    return 0;
}