1 条题解
-
0
问题分析
有 个学生站成一个圆圈,编号为 到 。学生之间的认识关系包括:
- 相邻关系:学生 认识 和 (模 )
- 闺蜜关系:有 对闺蜜,第 对分别站在位置 和
需要回答 次查询:从学生 到学生 的最短传球路径长度。
关键观察
-
图形结构:这实际上是一个环形图加上 条"直径边"
- 环形边:相邻学生之间的边
- 直径边:闺蜜对之间的边(连接相对位置)
-
路径性质:最短路径要么:
- 直接沿着环形走(不经过闺蜜边)
- 经过恰好一条闺蜜边(使用一个"传送门")
-
贪心选择:如果使用闺蜜边,应该选择离起点最近的闺蜜位置
算法思路
1. 距离计算
在环形上,两点 和 之间的最短距离为:
2. 传送门处理
对于每个闺蜜对 ,我们将其视为两个"传送门":
- 位置 的传送门可以跳到
- 位置 的传送门可以跳到
3. 查询计算
对于查询 :
- 计算直接距离:
- 找到离 最近的传送门 (使用二分查找)
- 计算通过传送门的距离:$\text{dist}(x, p) + 1 + \text{dist}(\text{配对}(p), y)$
- 取最小值
代码详解
#include <bits/stdc++.h> int main() { int n, m, q; scanf("%d%d%d", &n, &m, &q); // 存储所有传送门位置(每个闺蜜对有两个传送门) std::vector<int> portals(m + m); for (int i = 0; i < m; ++i) { int x; scanf("%d", &x); portals[i] = x; // 位置 k portals[i + m] = x + n; // 位置 k+N } // 环形距离计算函数 auto dist = [&](int x, int y) -> int { if (x < y) std::swap(x, y); // 两种走法:直接走 or 绕远路 return std::min(x - y, n + n + y - x); }; // 通过传送门的距离计算 auto dist_by_portal = [&](int x, int y, int z) -> int { // z: 传送门位置 // 配对传送门:如果 z ≤ n 则配对是 z+n,否则是 z-n int paired = (z <= n) ? (z + n) : (z - n); return dist(x, z) + 1 + dist(paired, y); }; // 对传送门位置排序,便于二分查找 std::sort(portals.begin(), portals.end()); while (q--) { int x, y; scanf("%d%d", &x, &y); // 方案1:直接传球(不经过传送门) int ans = dist(x, y); // 找到离 x 最近的传送门 // lower_bound 返回第一个 ≥ x 的位置 int i = std::lower_bound(portals.begin(), portals.end(), x) - portals.begin(); // 方案2:使用右边最近的传送门 if (i == portals.size()) { // x 比所有传送门都大,用第一个传送门(环形) ans = std::min(ans, dist_by_portal(x, y, portals.front())); } else { ans = std::min(ans, dist_by_portal(x, y, portals[i])); } // 方案3:使用左边最近的传送门 if (i == 0) { // x 比所有传送门都小,用最后一个传送门(环形) ans = std::min(ans, dist_by_portal(x, y, portals.back())); } else { ans = std::min(ans, dist_by_portal(x, y, portals[i - 1])); } printf("%d\n", ans); } return 0; }复杂度分析
-
预处理:
- 构建传送门数组:
- 排序:
-
每次查询:
- 二分查找:
- 距离计算:
-
总复杂度:
正确性证明
为什么最多只需要使用一个传送门?
假设使用两个传送门 和 ,路径为:
$$x \to p_1 \to \text{pair}(p_1) \to p_2 \to \text{pair}(p_2) \to y $$这等价于:
其中 到 的路径可以合并到环形路径中。因此使用一个传送门不会更差。
为什么只需要检查最近的传送门?
设 是离 最近的传送门, 是另一个传送门。
- 如果 在 和 之间:那么 ,但 可能更大
- 由于环形对称性,检查 及其相邻的两个传送门足够覆盖所有情况
- 1
信息
- ID
- 5748
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者