1 条题解
-
0
📝 题目大意
有 个人排成一列。给定数组 , 表示第 个人站在队伍最前面, 表示第 个人站在第 个人的正后方。保证信息唯一确定整个队列,要求按从前到后的顺序输出所有人的编号。
💡 解题思路
-
题目分析:每个 给出了一个"前驱关系"——第 个人紧跟在第 个人之后。由于题目保证存在且仅存在一种合法排列,这些关系构成了一条从队首到队尾的单向链表。,需要 解法。
-
算法推导:
- 朴素想法:对于每个人,我们需要知道"谁在我后面"。但原数组 存储的是"我在谁后面"(即前驱),不方便直接遍历。因此需要反向建表:对于每个 ,若 ,则
next[A_i] = i,表示第 个人后面是第 个人。 - 同时,找到 的那个人,他就是队首
head。 - 从
head出发,沿着next数组依次输出 个人,即为答案。 - 这本质上是一次链表构建 + 遍历,与 std.cpp 的逻辑完全一致:先读入 数组,遍历 时若 则记录
head = i,否则将next[A_i] = i;最后从head开始循环 次输出并更新cur = next[cur]。
- 朴素想法:对于每个人,我们需要知道"谁在我后面"。但原数组 存储的是"我在谁后面"(即前驱),不方便直接遍历。因此需要反向建表:对于每个 ,若 ,则
-
边界与细节:
- 输入保证恰好有一个 ,无需额外判断。
- 编号从 开始,因此数组开 大小,索引 不使用。
- 输出格式:每个编号之间用空格分隔,行末无多余空格,最后输出换行。
- 当 时,只有一个人,,
head = 1,next[1] = 0(未赋值),循环一次后cur = 0,但循环只执行 次,不会访问next[0],安全。
⏱️ 复杂度分析
- 时间复杂度:。读入 个数并构建
next数组需要 ,遍历输出同样需要 ,总复杂度 。 - 空间复杂度:。两个辅助数组
A和next各占 空间,无递归。
💻 标准代码 (C++)
#include <iostream> #include <vector> using namespace std; int main() { int N; cin >> N; vector<int> A(N + 1); // A[i] 表示第 i 个人的前驱信息 vector<int> next(N + 1, 0); // next[x] 表示站在第 x 个人正后方的人的编号 int head = -1; // 队首编号 for (int i = 1; i <= N; i++) { cin >> A[i]; if (A[i] == -1) { head = i; // 第 i 个人是队首 } else { next[A[i]] = i; // 第 i 个人站在第 A[i] 个人的正后方 } } int cur = head; // 从队首开始 for (int i = 0; i < N; i++) { cout << cur; if (i < N - 1) cout << " "; // 行末无多余空格 cur = next[cur]; // 移动到下一个人 } cout << endl; return 0; } -
- 1
信息
- ID
- 769
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者