队列安排
题目描述
一个学校里老师要将班上 NNN 个同学排成一列,同学被编号为 1∼N1\sim N1∼N,他采取如下的方法:
-
先将 111 号同学安排进队列,这时队列中只有他一个人;
-
2−N2-N2−N 号同学依次入列,编号为 iii 的同学入列方式为:老师指定编号为 iii 的同学站在编号为 1∼(i−1)1\sim(i-1)1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;
-
从队列中去掉 M(M<N)M(M<N)M(M<N) 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第 111 行为一个正整数 NNN,表示了有 NNN 个同学。
第 2∼N2\sim N2∼N行,第 iii 行包含两个整数 k,pk,pk,p,其中 kkk 为小于 iii 的正整数,ppp 为 000 或者 111。若 ppp 为$ 0$,则表示将 iii 号同学插入到 kkk 号同学的左边,ppp 为 111 则表示插入到右边。
第 N+1N+1N+1 行为一个正整数 MMM,表示去掉的同学数目。
接下来 MMM 行,每行一个正整数 xxx,表示将 xxx 号同学从队列中移去,如果 xxx 号同学已经不在队列中则忽略这一条指令。
输出格式
111 行,包含最多 NNN 个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。
样例 #1
样例输入 #1
4
1 0
2 1
1 0
2
3
3
样例输出 #1
2 4 1
提示
样例解释:
将同学 222 插入至同学 111 左边,此时队列为:
2 1
将同学 333 插入至同学 222 右边,此时队列为:
2 3 1
将同学 444 插入至同学 111 左边,此时队列为:
2 3 4 1
将同学 333 从队列中移出,此时队列为:
2 4 1
同学 333 已经不在队列中,忽略最后一条指令
最终队列:
2 4 1
数据范围
对于 20%20\%20% 的数据,有 1≤N≤101\leq N\leq 101≤N≤10;
对于 40%40\%40% 的数据,有 1≤N≤10001\leq N\leq 10001≤N≤1000;
对于 100%100\%100% 的数据,有 1≤N,M≤1000001\leq N,M\leq1000001≤N,M≤100000。
思路: 用链表储存学生
代码:
#include <bits/stdc++.h>
using namespace std;
struct Student{
int l, r, del = 0;
} stu[100005];
int main()
{
int n, m;
cin >> n;
stu[1].l = 0, stu[1].r = 0;
for(int i = 2; i <= n; i++){
int k, p;
cin >> k >> p;
if(p){
stu[i].l = k;
stu[i].r = stu[k].r;
stu[stu[k].r].l = i;
stu[k].r = i;
}else{
stu[i].r = k;
stu[i].l = stu[k].l;
stu[stu[k].l].r = i;
stu[k].l = i;
}
}
cin >> m;
for(int i = 0; i < m; i++){
int x;
cin >> x;
stu[x].del = 1;
}
for(int i = stu[0].r; i; i = stu[i].r){
if(!stu[i].del) cout << i << " ";
}
return 0;
}