题目描述
一个学校里老师要将班上NN个同学排成一列,同学被编号为1\sim N1∼N,他采取如下的方法:
-
先将11号同学安排进队列,这时队列中只有他一个人;
-
2-N2−N号同学依次入列,编号为i的同学入列方式为:老师指定编号为i的同学站在编号为1\sim (i -1)1∼(i−1)中某位同学(即之前已经入列的同学)的左边或右边;
-
从队列中去掉M(M<N)M(M<N)个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入输出格式
输入格式:
第11行为一个正整数NN,表示了有NN个同学。
第2-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
为了提高链表的查找速度,用一个指针数组来记录每个节点的前面一个指针的位置。
#include<iostream>
#include<vector>
#include<climits>
#include<stack>
#include<string>
using namespace std;
typedef struct N
{
int val;
struct N* next;
N(int x) :val(x), next(NULL) {}
} Node;
int main()
{
int n;
cin >> n;
vector<Node*> res(n+1);
Node* p = new Node(0);
Node *head = p;
Node* tt = new Node(1);
p->next = tt;
p = p->next;
res[1] = head;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
tt = res[a];
if (b == 0)
{
Node* tmp = new Node(i + 1);
tmp->next = tt->next;
tt->next = tmp;
res[i + 1] = tt;
res[a] = tmp;
}
else if (b == 1)
{
tt = tt->next;
int temp;
if (tt->next != NULL)
{
temp = tt->next->val;
Node* tmp = new Node(i + 1);
tmp->next = tt->next;
tt->next = tmp;
res[i + 1] = tt;
res[temp] = tmp;
}
else
{
Node* tmp = new Node(i + 1);
tmp->next = tt->next;
tt->next = tmp;
res[i + 1] = tt;
}
}
}
int r;
cin >> r;
for (int i = 0; i < r; i++)
{
int num;
cin >> num;
tt = res[num];
if (tt == NULL)
continue;
Node *tmp = tt->next;
tt->next = tt->next->next;
res[tmp->val] = NULL;
if(tt->next!=NULL)
res[tt->next->val] = tt;
delete tmp;
}
tt = head;
while (tt->next != NULL)
{
cout << tt->next->val<<" ";
tt = tt->next;
}
return 0;
}