1 条题解
-
0
📝 题目大意
有 个人排成一列,给定他们从前往后的编号序列 。处理 个查询,每次给定两个编号 和 ,输出站在更前面的那个人的编号。
💡 解题思路
-
题目分析:题目本质上是在问:给定编号 和 ,它们在序列 中谁的下标更小(即谁更靠前)。注意输入保证 (编号大小关系),但这与站位无关——站位由序列中出现的顺序决定。
-
算法推导:
- 朴素想法:每次查询时遍历 数组,找到 和 各自的位置,比较后输出。这样每个查询 ,总复杂度 ,在 下完全可行,但不够优雅。
- 优化思路:注意到 是 到 的一个排列,我们可以建立一个反向映射——
pos[x]表示编号为 的人在队伍中的位置(第几位)。读入时,对于第 个读入的 ,令pos[p] = i。 - 查询时,直接比较
pos[A]和pos[B]:位置更小的人站在更前面,输出其编号即可。每个查询 。
-
边界与细节:
- 编号从 开始,因此
pos数组需要开到 。 - 题目保证 ,且根据条件 仅指数值大小,不代表站位顺序,不要被误导。
- 由于
pos[p]的值域是 ,不会出现位置相等的情况,无需处理平局。
- 编号从 开始,因此
⏱️ 复杂度分析
- 时间复杂度:读入并建立
pos数组 ,每个查询 ,总复杂度 。 - 空间复杂度:
pos数组占用 额外空间。
💻 标准代码 (C++)
#include <iostream> #include <vector> using namespace std; int main() { int N; cin >> N; // pos[x] 表示编号为 x 的人站在第几个位置(1-indexed) vector<int> pos(N + 1); for (int i = 1; i <= N; i++) { int p; cin >> p; pos[p] = i; // 编号 p 的人在第 i 位 } int Q; cin >> Q; while (Q--) { int A, B; cin >> A >> B; // 位置更小的那个人站在更前面 if (pos[A] < pos[B]) { cout << A << endl; } else { cout << B << endl; } } return 0; } -
- 1
信息
- ID
- 782
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者