1 条题解
-
0
题解
问题分析
在困难版本中, 和 都可以达到 ,所有测试用例中 的总和与 的总和均不超过 。我们需要处理多个老师的情况,并回答 个关于 David 位置的查询。
与简单版本类似,David 想最大化被抓的时间,老师们想最小化这个时间。关键在于确定 David 相对于老师们的区间位置。
核心思路
将老师的位置排序后,David 的位置相对于老师集合可以分为三种情况:
情况 1:David 在所有老师左侧
即 David 的位置 满足 ( 是最左边的老师)。
在这种情况下,David 的最佳策略是尽可能向左逃,最远可以到达格子 。最左边的老师需要从 移动到 ,距离为 。其他老师虽然也在追,但最左边的老师会最先抓住 David。
因此,所需时间为:
情况 2:David 在所有老师右侧
即 David 的位置 满足 ( 是最右边的老师)。
类似地,David 的最佳策略是尽可能向右逃,最远可以到达格子 。最右边的老师需要从 移动到 ,距离为 。
因此,所需时间为:
情况 3:David 在两位老师之间
即存在某个 (),使得 。
此时,David 的最佳策略是移动到这两个老师之间的中间位置。由于这两位老师从两侧同时逼近,David 可以停留在中间,使两位老师需要相同的步数才能同时到达。
两位老师之间的初始距离为 。当 David 位于正中间时,两位老师各需移动 步(如果距离为奇数,则中间有两个格子,选择任意一个均可)。
因此,所需时间为: $ans= \left\lfloor \frac{b_{k+1} - b_k}{2} \right\rfloor$
注意:在代码中直接使用整数除法 即可,因为 C++ 整数除法会自动向下取整。
关键观察:David 位于哪两个老师之间是重要的,因为不同的相邻老师对之间的间隔不同,David 会移动到该间隔的中间位置,而时间取决于该间隔的长度。David 初始位置并不影响最终结果(只要他在该间隔内),因为他可以移动到中间位置。
算法步骤
- 读入
- 读入 个老师的位置并排序
- 对于每个查询 :
- 使用二分查找找到第一个大于等于 的老师位置
- 如果 ( 小于所有老师):输出
- 如果 ( 大于所有老师):输出
- 否则( 在 和 之间):输出
标程解析
#include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; // 测试用例数 while (t--) { int n, m, q; cin >> n >> m >> q; vector<int> a(m); for (int i = 0; i < m; i++) cin >> a[i]; sort(a.begin(), a.end()); // 排序老师位置 for (int i = 1; i <= q; i++) { int b; cin >> b; // 找到第一个大于等于 b 的老师位置 int k = upper_bound(a.begin(), a.end(), b) - a.begin(); if (k == 0) cout << a[0] - 1 << ' '; // 情况1: b < a[0] else if (k == m) cout << n - a[m - 1] << ' '; // 情况2: b > a[m-1] else cout << (a[k] - a[k - 1]) / 2 << ' '; // 情况3: a[k-1] < b < a[k] } cout << "\n"; } return 0; }代码说明:
upper_bound返回第一个大于 的老师位置, 表示该老师的索引- 若 ,说明 比所有老师都小(情况1)
- 若 ,说明 比所有老师都大(情况2)
- 否则, 在 和 之间(情况3)
复杂度分析
- 每个测试用例排序老师位置:
- 每个查询二分查找:
- 所有测试用例的总复杂度:
- 由于 ,,总复杂度可接受
示例验证
输入:
2 8 1 1 6 3 10 3 3 1 4 8 2 3 10处理过程:
测试用例 1:
- 查询 :(因为 )
- 情况1:输出
测试用例 2:
- (已排序)
- 查询 :()
- 情况3:输出
- 查询 :
- 情况3:输出
- 查询 :
- 情况2:输出
输出:
5 1 1 2与示例输出一致。
关键结论
- David 的最佳策略总是移动到最近的"安全区间"的中间位置
- 对于左侧或右侧的区间,边界是 或
- 对于中间的区间,边界是相邻的老师
- 答案只取决于区间长度,与 David 的初始位置无关(只要他在该区间内)
- 使用二分查找快速定位 David 所在的区间
- 1
信息
- ID
- 6194
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者