链表板子之排队模拟实现
前言
自己参考洛谷深入浅出的题解手搓的一个双向链表的板子,更适合我自己的胃口,特此记录
题目描述
一个学校里老师要将班上 N 个同学排成一列,同学被编号为 1 ~ N,他采取如下的方法:
先将 1 号同学安排进队列,这时队列中只有他一个人;
2 ~ N 号同学依次入列,编号为 i 的同学入列方式为:老师指定编号为 i 的同学站在编号为 1 ~ (i - 1) 中某位同学(即之前已经入列的同学)的左边或右边;
从队列中去掉 M 个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第一行一个整数 N ,表示了有 N 个同学。
第 2 ~ N 行,第 i 行包含两个整数 k,p,其中 k 为小于 i 的正整数,p 为 0 或者 1。若 p 为 0,则表示将 i 号同学插入到 k 号同学的左边,p 为 1 则表示插入到右边。
第 N+1 行为一个整数 M,表示去掉的同学数目。
接下来 M 行,每行一个正整数 x,表示将 x 号同学从队列中移去,如果 x 号同学已经不在队列中则忽略这一条指令。
输出格式
一行,包含最多 N 个空格隔开的整数,表示了队列从左到右所有同学的编号。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include <bits/stdc++.h> using namespace std; typedef long long LL;
struct node { int pre, nxt, key; node(int _pre = 0, int _nxt = 0, int _key = 0) { pre = _pre, nxt = _nxt, key = _key; } };
node s[100010]; int indexx[100010]; int tot = 1;
void ins_front(int x, int y) { int now = indexx[x]; s[++tot] = node(s[now].pre, now, y); indexx[y] = tot; s[s[now].pre].nxt = indexx[y]; s[now].pre = indexx[y]; }
void ins_back(int x, int y) { int now = indexx[x]; s[++tot] = node(now, s[now].nxt, y); indexx[y] = tot; s[s[now].nxt].pre = indexx[y]; s[now].nxt = indexx[y]; }
void del(int x) { int now = indexx[x]; s[s[now].pre].nxt = s[now].nxt; s[s[now].nxt].pre = s[now].pre; indexx[x] = 0; }
int main() { LL n, m; s[0] = node(0, 1, 0); s[1] = node(0, 0, 1); indexx[1] = 1; cin >> n; for (int i = 2; i <= n; i++) { int k, p; cin >> k >> p; if (p == 0) { ins_front(k, i); } else if (p == 1) { ins_back(k, i); } } cin >> m; while (m--) { int x; cin >> x; if (indexx[x] == 0) continue; del(x); } int now = s[0].nxt; while (now) { cout << s[now].key << " "; now = s[now].nxt; } return 0; }
|