队列安排
题目描述
一个学校里老师要将班上 N N N 个同学排成一列,同学被编号为 1 ∼ N 1\sim N 1∼N,他采取如下的方法:
-
先将 1 1 1 号同学安排进队列,这时队列中只有他一个人;
-
2 − N 2-N 2−N 号同学依次入列,编号为 i i i 的同学入列方式为:老师指定编号为 i i i 的同学站在编号为 1 ∼ ( i − 1 ) 1\sim(i-1) 1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;
-
从队列中去掉 M ( M < N ) M(M<N) M(M<N) 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第 1 1 1 行为一个正整数 N N N,表示了有 N N N 个同学。
第 2 ∼ N 2\sim N 2∼N行,第 i i i 行包含两个整数 k , p k,p k,p,其中 k k k 为小于 i i i 的正整数, p p p 为 0 0 0 或者 1 1 1。若 p p p 为$ 0$,则表示将 i i i 号同学插入到 k k k 号同学的左边, p p p 为 1 1 1 则表示插入到右边。
第 N + 1 N+1 N+1 行为一个正整数 M M M,表示去掉的同学数目。
接下来 M M M 行,每行一个正整数 x x x,表示将 x x x 号同学从队列中移去,如果 x x x 号同学已经不在队列中则忽略这一条指令。
输出格式
1 1 1 行,包含最多 N N N 个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。
样例 #1
样例输入 #1
4
1 0
2 1
1 0
2
3
3
样例输出 #1
2 4 1
提示
样例解释:
将同学 2 2 2 插入至同学 1 1 1 左边,此时队列为:
2 1
将同学 3 3 3 插入至同学 2 2 2 右边,此时队列为:
2 3 1
将同学 4 4 4 插入至同学 1 1 1 左边,此时队列为:
2 3 4 1
将同学 3 3 3 从队列中移出,此时队列为:
2 4 1
同学 3 3 3 已经不在队列中,忽略最后一条指令
最终队列:
2 4 1
数据范围
对于 20 % 20\% 20% 的数据,有 1 ≤ N ≤ 10 1\leq N\leq 10 1≤N≤10;
对于 40 % 40\% 40% 的数据,有 1 ≤ N ≤ 1000 1\leq N\leq 1000 1≤N≤1000;
对于 100 % 100\% 100% 的数据,有 1 ≤ N , M ≤ 100000 1\leq N,M\leq100000 1≤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;
}