P3853 [TJOI2007] 路标设置

P3853 [TJOI2007] 路标设置

题目背景

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

题目描述

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

输入格式

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

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

输出格式

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

输入输出样例 #1

输入 #1

1
2
101 2 1
0 101

输出 #1

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\operatorname{log}n)$ ,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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;
}