题目描述
一个学校里老师要将班上 𝑁 个同学排成一列,同学被编号为 1∼𝑁,他采取如下的方法:
-
先将 1 号同学安排进队列,这时队列中只有他一个人;
-
2∼𝑁 号同学依次入列,编号为 𝑖 的同学入列方式为:老师指定编号为 𝑖 的同学站在编号为 1∼(𝑖−1) 中某位同学(即之前已经入列的同学)的左边或右边;
-
从队列中去掉 𝑀 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第一行一个整数 𝑁,表示了有 𝑁 个同学。
第 2∼𝑁 行,第 𝑖 行包含两个整数 𝑘,𝑝,其中 𝑘 为小于 𝑖 的正整数,𝑝 为 0 或者 1。若 𝑝 为 0,则表示将 𝑖 号同学插入到 𝑘 号同学的左边,𝑝 为 1 则表示插入到右边。
第 𝑁+1 行为一个整数 𝑀,表示去掉的同学数目。
接下来 𝑀 行,每行一个正整数 𝑥,表示将 𝑥 号同学从队列中移去,如果 𝑥 号同学已经不在队列中则忽略这一条指令。
输出格式
一行,包含最多 𝑁 个空格隔开的整数,表示了队列从左到右所有同学的编号。
输入输出样例
输入 #1
4 1 0 2 1 1 0 2 3 3
输出 #1
2 4 1
说明/提示
【样例解释】
将同学 2 插入至同学 1 左边,此时队列为:
2 1
将同学 3 插入至同学 2 右边,此时队列为:
2 3 1
将同学 4 插入至同学 1 左边,此时队列为:
2 3 4 1
将同学 3 从队列中移出,此时队列为:
2 4 1
同学 3 已经不在队列中,忽略最后一条指令
最终队列:
2 4 1
【数据范围】
对于 20% 的数据,1≤𝑁≤10。
对于 40% 的数据,1≤𝑁≤1000。
对于 100% 的数据,1<𝑀≤𝑁≤105。
完整代码
#include <bits/stdc++.h>
using namespace std;
int n, m, k, p, nxt[100005];
bool inQueue[100005], pr[100005];
deque<int> queue;
int main() {
int n, m, k, p, nxt[100005];
int isInQueue[100005], lst[100005];
cin >> n;
nxt[0] = 1;
isInQueue[1] = 1;
for (int i = 2; i <= n; i++) {
isInQueue[i] = 1;
cin >> k >> p;
if (!p) {
nxt[lst[k]] = i;
lst[i] = lst[k];
lst[k] = i;
nxt[i] = k;
} else {
lst[nxt[k]] = i;
nxt[i] = nxt[k];
nxt[k] = i;
lst[i] = k;
}
}
cin >> m;
for (int i = 1; i <= m; i++) {
int x;
cin >> x;
if (!isInQueue[x])
continue;
isInQueue[x] = 0;
int t = lst[x];
nxt[lst[x]] = nxt[x];
lst[nxt[x]] = t;
}
int now = nxt[0];
while (now != 0) {
cout << now;
now = nxt[now];
if (now != 0)
cout << " ";
}
return 0;
}
题解
-
初始化,定义STL:
- 我们首先定义
nxt
数组来表示每个同学的下一个同学,lst
数组表示每个同学的上一个同学,isInQueue
数组用于标记同学是否在队列中。 - 对于队列本身,我们可以使用
deque
类型来实现,因为它支持双端操作。
- 我们首先定义
-
输入:
- 输入同学数量
n
。 - 对于每个同学
i
,输入他的插入位置k
和插入方向p
。- 如果
p
为 0,则将同学i
插入到同学k
的左边。 - 如果
p
为 1,则将同学i
插入到同学k
的右边。 - 在输入时,更新
nxt
和lst
数组以及标记该同学在队列中。
- 如果
- 输入同学数量
-
处理:
- 输入需要出队的同学数目
m
。 - 对于每个需要出队的同学的编号
x
,更新对应同学的isInQueue
为 0,并更新他的上一个同学和下一个同学的关系。
- 输入需要出队的同学数目
-
输出:根据
nxt
数组从左到右输出队列中所有同学的编号,直到遍历完整个队列。