排队买饭(链表) SDUT OJ4516

博客围绕理工大食堂排队买饭问题展开,涉及两种队列操作:输入1时删除最左元素及相同编号元素;输入2时在首个指定编号元素后插入新元素。需判断每次操作后队列是否为空,最后输出最终序列,并给出了输入输出格式及补充样例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排队买饭

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

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");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值