排队买饭
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
理工大的食堂到了饭点人可以说是相当多了,按理来说排队的时候先来的同学应该会先走,但实际情况可能并不一样,我们注意到对于一个队列往往由以下两种操作组成
当输入 1 时:代表队列最左面的同学完成了买饭操作,由于他会帮他的好朋友一起买,所以买完饭后会叫上所有与他编号相同的好朋友一起走,如果输入1时队伍已经为空则不进行任何操作。换句话说,如果序列不为空则会在序列中删除最左边的一个元素和与之编号相同的所有元素,否则不删除。
当输入 2 时:代表编号为 b 的同学想要插队买饭,由于他与编号为 a 的同学是好朋友,他会插入到队列从左往右的第一个编号为 a 的同学右边,如果队伍中没有编号为 a 的同学,他就会伤心的离开。换句话说,会在队列的从左往右的第一个 a 后面插入一个 b,如果队列中没有 a 则不插入。
需要注意的是,每次操作后都需要你判断一下队列是否为空,如果为空则输出“EMPTY”。
最后一行输出所有操作后的序列。
Input
第一行一个数 n 代表初始时序列中的元素 ( n<=1e5)
第二行 n个 int 范围内的数,最多有1000个不同的。
第三行一个数 m 代表操作的次数。(m<=1e5)
后面m行每行第一个数代表操作种类。
如果操作为 2 则再输入两个数 a,b。
Output
对于每次操作,如果操作后队列为空,则输出"EMPTY"。
所有操作完成后输出最终的序列。
(最下方提示有补充测试样例)
Sample Input
6 1 1 4 3 1 2 3 2 4 5 1 1
Sample Output
5 3 2
Hint
补充样例:
input:
6
1 1 4 3 1 2
5
2 6 5
1
1
1
1
output:
EMPTY
此题目中有歧义:“EMPTY”的输出应该是每一次操作无论成功与否,在返回前都会判断是否为空,若链表为空,则输出
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int data;
struct node *next;
};
struct node *Sequence_Linked_List(int);
void one(struct node *);
void two(struct node *, int, int);
void output(struct node *);
int main()
{
int n, m, a, b, x;
struct node *head;
scanf("%d", &n);
head = Sequence_Linked_List(n);
scanf("%d", &m);
while(m--)
{
scanf("%d", &x);
if(x == 1)
{
one(head);
}
else
{
scanf("%d %d", &a, &b);
two(head, a, b);
}
}
output(head);
return 0;
}
struct node *Sequence_Linked_List(int n)
{///顺序建立链表,输入队伍中编号
struct node *head, *tail, *p;
head = (struct node *)malloc(sizeof(struct node));
head->next = NULL;
tail = head;
while(n--)
{
p = (struct node *)malloc(sizeof(struct node));
scanf("%d", &p->data);
p->next = NULL;
tail->next = p;
tail = p;
}
tail->next = NULL;
return head;
};
void one(struct node *head)
{///如果序列不为空,在序列中删除最左边的一个元素和与之编号相同的所有元素
///否则不进行操作
struct node *q, *p;
int x;
if(head->next == NULL)
{///当序列为空时,不进行操作
printf("EMPTY\n");
return;
}
else
{
q = head;
p = q->next;
x = head->next->data;/// x = p->data 记录最左边第一个元素的编号
while(p)
{
if(p->data == x)
{///当队列中存在与 x 相同的编号,则删除该元素
q->next = p->next;
free(p);
p = q->next;
if(head->next == NULL)
{///每一次操作后,判断队列是否为空,如果为空,则输出"EMPTY"并返回
printf("EMPTY\n");
return;
}
}
else
{
q = p;
p = p->next;
}
}
}
}
void two(struct node *head, int a, int b)
{///如果有编号为 a 的同学,则在 a 后插入编号为 b 的结点
///若没有编号为 a 的同学,则不进行操作
struct node *p, *k;
p = head->next;
while(p)
{
if(p->data == a)
{///若找到编号为 a 的同学,则在其后面插入编号为 b 的结点
k = (struct node *)malloc(sizeof(struct node));
k->data = b;
k->next = p->next;
p->next = k;
break;
}
p = p->next;
}
if(head->next == NULL)
{
printf("EMPTY\n");
return;
}
}
void output(struct node *head)
{
struct node *p;
p = head->next;
while(p)
{
if(p == head->next)
{
printf("%d", p->data);
}
else
{
printf(" %d", p->data);
}
p = p->next;
}
printf("\n");
}