题目描述
一个学校里老师要将班上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
说明
样例解释:
将同学22插入至同学11左边,此时队列为:
2 121
将同学33插入至同学22右边,此时队列为:
2 3 1231
将同学44插入至同学11左边,此时队列为:
2 3 4 12341
将同学33从队列中移出,此时队列为:
2 4 1241
同学33已经不在队列中,忽略最后一条指令
最终队列:
2 4 1241
数据范围
对于20%20%的数据,有N≤10N≤10;
对于40%40%的数据,有N≤1000N≤1000;
对于100%100%的数据,有N, M≤100000N,M≤100000。
这道题目我首先用的是链表做的,超时了
只过了两个点
#include <bits/stdc++.h>
#include <malloc.h>
using namespace std;
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}Node,*BNode;
int a[100005];
void initNode(BNode *head)
{
*head = (Node*)malloc(sizeof(Node));
Node *p = (Node*)malloc(sizeof(Node));
p->data = 1;
p->next = NULL;
(*head)->next = p;
}
void insert1(BNode *head,int k,int x)
{
int n = 0;
BNode p = (*head)->next,q,t;
q = (BNode)malloc(sizeof(Node));
q->data = x;
q->next = NULL;
t = (*head);
while(p->data != k ){
t = p;
n++;
p = p->next;
}
if(n == 0){
q->next = p;
(*head)->next = q;
}else {
t->next = q;
q->next = p;
}
}
void insert2(BNode *head,int k,int x)
{
BNode p = (*head)->next,q;
q = (BNode)malloc(sizeof(Node));
q->data = x;
q->next = NULL;
while(p->data != k){
p = p->next;
}
BNode t = p->next;
p->next = q;
q->next = t;
}
int main()
{
int n;
BNode head,p;
//对链表进行初始化
initNode(&head);
scanf("%d",&n);
for(int i = 2;i <= n;i++){
int k,p;
scanf("%d %d",&k,&p);
if(p == 0){
insert1(&head,k,i);
}else {
insert2(&head,k,i);
}
}
int m;
scanf("%d",&m);
for(int i = 0;i < m;i++){
int x;
scanf("%d",&x);
a[x] = 1;
}
p = head->next;
while(p != NULL){
DataType x;
x = p->data;
if(a[x] == 0)
printf("%d ",x);
p = p->next;
}
return 0;
}
然后看到有个用的是模拟,我也就尝试了下,AC了
#include <bits/stdc++.h>
/*
第二列表示这是第i个数
第一列表示这是第i个数左边数的值
第三列表示这是第i个数右边数的值
*/
int a[100005][3];
/*
用来记录某个数是否被删除
x没被删除则b[x] = 0;否则b[x] = 1;
*/
int b[100005];
int main()
{
int n;
/**/
a[1][1] = 1;
scanf("%d",&n);
for(int i = 2;i <= n;i++){
/**/
a[i][1] = i;
int k,p;
scanf("%d %d",&k,&p);
/*
这是模拟的过程,可以手动的算出来
自己动手,要不然看不懂
*/
if(p == 0){
a[i][2] = k;
a[i][0] = a[a[i][2]][0];
a[a[k][0]][2] = i;
a[k][0] = i;
}else {
a[i][0] = k;
a[i][2] = a[a[i][0]][2];
a[a[k][2]][0] = i;
a[k][2] = i;
}
}
int m;
scanf("%d",&m);
for(int i = 0;i < m;i++){
int x;
scanf("%d",&x);
b[x] = 1;
}
int k = 1;
while(a[k][0] != 0) k++;
while(k != 0){
if(b[a[k][1]] == 0){
printf("%d ",a[k][1]);
}
k = a[k][2];
}
/*
for(int i = 1;i <= n;i++){
printf("%d %d %d\n",a[i][0],a[i][1],a[i][2]);
}
*/
return 0;
}