题目描述一个学校里老师要将班上 NN 个同学排成一列,同学被编号为 1\sim N1∼N,他采取如下的方法:
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。 输入格式第 11 行为一个正整数 NN,表示了有 NN 个同学。 第 2\sim N2∼N行,第 ii 行包含两个整数 k,pk,p,其中 kk 为小于 ii 的正整数,pp 为 00 或者 11。若 pp 为00,则表示将 ii 号同学插入到 kk 号同学的左边,pp 为 11 则表示插入到右边。 第 N+1N+1 行为一个正整数 MM,表示去掉的同学数目。 接下来 MM 行,每行一个正整数 xx,表示将 xx 号同学从队列中移去,如果 xx 号同学已经不在队列中则忽略这一条指令。 输出格式11 行,包含最多 NN 个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。 输入输出样例输入 #1复制 4 1 0 2 1 1 0 2 3 3 输出 #1复制 2 4 1 说明/提示样例解释: 将同学 22 插入至同学 11 左边,此时队列为:
将同学 33 插入至同学 22 右边,此时队列为:
将同学 44 插入至同学 11 左边,此时队列为:
将同学 33 从队列中移出,此时队列为:
同学 33 已经不在队列中,忽略最后一条指令 最终队列:
数据范围 对于 20\%20% 的数据,有 1\leq N\leq 101≤N≤10; 对于 40\%40% 的数据,有 1\leq N\leq 10001≤N≤1000; 对于 100\%100% 的数据,有 1\leq N,M\leq1000001≤N,M≤100000。 | |
---|---|
本来是双向链表的例题,但是感觉好麻烦就直接用两个数组做了(懒)
分别用left和right数组表示其两边的人是谁。
#include<bits/stdc++.h>
using namespace std;
int n, l[100007], r[100007];
int main() {
scanf("%d", &n);
int i = 1, k, p, ll = 1, m, x;
--n;
while (n--) {
i++;
scanf("%d%d", &k, &p);
if (p) {
if (r[k]) {
r[i] = r[k];
l[r[k]] = i;
}
l[i] = k;
r[k] = i;
} else {
if (l[k]) {
l[i] = l[k];
r[l[k]] = i;
} else ll = i;
r[i] = k;
l[k] = i;
}
}
scanf("%d", &m);
while (m--) {
scanf("%d", &x);
if (l[x])
r[l[x]] = r[x];
else {
if (r[x])
ll = r[x];
}
if (r[x])
l[r[x]] = l[x];
r[x] = 0;
l[x] = 0;
}
int j = ll;
while (r[j]) {
printf("%d ", j);
j = r[j];
}
printf("%d\n", j);
return 0;
}