碰到了一道题发现忘了数组模拟双链表怎么实现了,顺便复习了一下。然后解决问题。
双链表模板题:
实现一个双链表,双链表初始为空,支持 5 种操作:
- 在最左侧插入一个数;
- 在最右侧插入一个数;
- 将第 k 个插入的数删除;
- 在第 k 个插入的数左侧插入一个数;
- 在第 k 个插入的数右侧插入一个数
现在要对该链表进行 M 次操作,进行完所有操作后,从左到右输出整个链表。
注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作过程中一共插入了 n 个数,则按照插入的时间顺序,这 n 个数依次为:第 1 个插入的数,第 2 个插入的数,…第 n 个插入的数。
输入格式
第一行包含整数 M,表示操作次数。
接下来 M 行,每行包含一个操作命令,操作命令可能为以下几种:
L x
,表示在链表的最左端插入数 x。R x
,表示在链表的最右端插入数 x。D k
,表示将第 k 个插入的数删除。IL k x
,表示在第 k 个插入的数左侧插入一个数。IR k x
,表示在第 k 个插入的数右侧插入一个数。
输出格式
共一行,将整个链表从左到右输出。
数据范围
1≤M≤100000
所有操作保证合法。
输入样例:
10
R 7
D 1
L 3
IL 2 10
D 3
IL 2 7
L 8
R 9
IL 4 7
IR 2 2
输出样例:
8 7 7 3 2 9
代码:
#include <iostream> #include <string> using namespace std; const int N=1e5+10; int l[N],r[N],idx; int e[N]; void init() { l[1]=0; r[0]=1; idx=2; } void insert(int k,int x) { e[idx]=x; l[idx]=k; r[idx]=r[k]; l[r[k]]=idx; r[k]=idx++; } void remove_k(int k) { l[r[k]]=l[k]; r[l[k]]=r[k]; } int main() { int n; cin>>n; init(); while(n--) { string s; int x,k; cin>>s; if(s=="L") { cin>>x; insert(0,x); } else if(s=="R") { cin>>x; insert(l[1],x); } else if(s=="D") { cin>>k; remove_k(k+1); } else if(s=="IL") { cin>>k>>x; insert(l[k+1],x); } else { cin>>k>>x; insert(k+1,x); } } for(int i=r[0];i!=1;i=r[i]) cout<<e[i]<<' '; return 0; }
下面是本题:
题目描述
一个学校里老师要将班上 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 个空格隔开的整数,表示了队列从左到右所有同学的编号。
输入输出样例
输入 #14 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≤N≤10。
对于 40% 的数据,1≤N≤1000。
对于 100% 的数据,1<M≤N≤105。
代码:
#include <iostream> #include <cstdio> using namespace std; const int N=1e5+10; int l[N],r[N],e[N],idx; bool st[N]; void init() { l[1]=0; r[0]=1; idx=2; } void insert(int k,int x) { e[idx]=x; l[idx]=k; r[idx]=r[k]; l[r[k]]=idx; r[k]=idx++; } int main() { init(); int n; scanf("%d",&n); insert(0,1); for(int i=2;i<=n;i++) { int k,p; scanf("%d %d",&k,&p); if(p==0) insert(l[k+1],i); else insert(k+1,i); } int m; scanf("%d",&m); while(m--) { int x; scanf("%d",&x); st[x]=true; } for(int i=r[0];i!=1;i=r[i]) { int j=e[i]; if(st[j]) continue; printf("%d ",j); } return 0; }
标签:同学,insert,idx,插入,队列,int,P1160,双链
From: https://www.cnblogs.com/yaowww/p/17331403.html