P3853 [TJOI2007] 路标设置

P3853 [TJOI2007] 路标设置

题目背景

B 市和 T 市之间有一条长长的高速公路,这条公路的某些地方设有路标,但是大家都感觉路标设得太少了,相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题,我们把公路上相邻路标的最大距离定义为该公路的“空旷指数”。

题目描述

现在政府决定在公路上增设一些路标,使得公路的“空旷指数”最小。他们请求你设计一个程序计算能达到的最小值是多少。请注意,公路的起点和终点保证已设有路标,公路的长度为整数,并且原有路标和新设路标都必须距起点整数个单位距离。

输入格式

第 $1$ 行包括三个数 $L,N,K$,分别表示公路的长度,原有路标的数量,以及最多可增设的路标数量。

第 $2$ 行包括递增排列的 $N$ 个整数,分别表示原有的 $N$ 个路标的位置。路标的位置用距起点的距离表示,且一定位于区间 $[0,L]$ 内。

输出格式

输出 $1$ 行,包含一个整数,表示增设路标后能达到的最小“空旷指数”值。

输入输出样例 #1

输入 #1

101 2 1
0 101

输出 #1

51

说明/提示

公路原来只在起点和终点处有两个路标,现在允许新增一个路标,应该把新路标设在距起点 $50$ 或 $51$ 个单位距离处,这样能达到最小的空旷指数 $51$。

$50%$ 的数据中,$2 \leq N \leq 100$,$0 \leq K \leq 100$。

$100%$ 的数据中,$2 \leq N \leq 100000$, $0 \leq K \leq100000$。

$100%$ 的数据中,$0 < L \leq 10000000$。

思路分析 + 代码实现

这道题跟 P2678 [NOIP 2015 提高组] 跳石头 很像,都是二分,但是本题求的是“最大的最小”,而且在细节处理上不太一样。二分答案,当所用的路标小于 $K$ 时,说明可能还能取到更小的“空旷指数”,所以在记录答案的同时令 r = mid - 1; 。时间复杂度为 $O(n \log n)$ ,代码如下:

#include <bits/stdc++.h>
using namespace std;
constexpr int MAXN = 1e5 + 5;
int a[MAXN];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int L, N, K, ans;
    cin >> L >> N >> K;
    for(int i = 1; i <= N; i++)
        cin >> a[i];
    int l = 1, r = L;
    while (l <= r) {
        int mid = (l + r) / 2, cnt = 0;
        for(int i = 1; i < N; i++) {
            int t = a[i] + mid;
            if (t < a[i + 1])
                while (t < a[i + 1]) {
                    cnt++;
                    t += mid;
                }
        }
        if (cnt <= K) {
            ans = mid;
            r = mid - 1;
        } else l = mid + 1;
    }
    cout << ans;
    return 0;
}
使用 Hugo 构建
主题 StackJimmy 设计