AcWing 132. 小组队列(队列模拟题)

这篇博客讨论了一个关于队列模拟的编程问题。题目描述了有多个小组成员按照特定规则进行排队,如果队列中已有同一小组成员,新来者会插队,否则排在队尾。解决方案涉及使用多个小队列(queue<int>[N])和哈希表(ha)来跟踪成员及其所属小组,并用数组(st)记录小组出现状态。博主提供了详细的代码实现,包括处理入队和出队操作的情况。通过这个例子,读者可以学习到如何运用数据结构解决实际问题。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:

n 个小组 要进行排队,每个小组中有若干个人。

当一个人来到队伍时,

  • 如果 队伍中已经有自己小组的成员,他就直接插队排在自己小组成员的后面。
  • 否则,就站在队伍的最后面。

给定 不超过 2 * 10 ^ 5 个入队指令编号为 X 的人 来到队伍)和 出队指令队头的人 出队),输出 出队的顺序

思路:

这题显然需要用到很多 小队列,因此为了方便,我们先直接开 Nqueue 作为 总队列queue<int>[N]

用一个 哈希表 ha,记录 所有输入的成员编号 所属的 小组编号

用一个 数组 st,记录 输入成员所属的小组 是否出现在 总的队列 中,如果 0 则未出现过,不为 0 则同时记录 该小组 出现在 第几段 小队列 之中。

之后就是模拟,具体详见代码。

注意:

  • 出队 的时候,当 某个小队列的大小为 0 一定要记得将 st 数组 对应处 0
代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>

using namespace std;
const int N = 1010;

map<int, int> ha;//成员编号对应的组别编号
int st[N];//判断有无某个组别的成员出现在队列中,同时记录该组别在第几组小队列中

int main()
{
    int T = 1; 
    int Cnt = 0;
    while (~scanf("%d", &T), T)
    {
        queue<int> qq[N];
        memset(st, false, sizeof st);
        ha.clear();

        int h = 1, t = 0;

        while (T--)
        {
            int cnt; scanf("%d", &cnt);
            ++t;
            for (int i = 0; i < cnt; ++i)
            {
                int tag; scanf("%d", &tag);
                ha[tag] = t;
            }
        }

        char op[20];

        h = 1, t = 0;

        printf("Scenario #%d\n", ++Cnt);
        while (~scanf("%s", op), *op != 'S')
        {
            if (*op == 'E')
            {
                int x; scanf("%d", &x);
                //cout << "ha[x] " << ha[x] << '\n';
				//当总队列中还没有 x 所属组别的成员,则开一个新的小队列并压入 x
                if (!st[ha[x]])	
                {
                    st[ha[x]] = ++t;
                    qq[t].push(x);
                }
                else	//否则压入他所属组别的小队列
                {
                    qq[st[ha[x]]].push(x);
                }
            }
            else
            {
                if (qq[h].size())
                {
                    int top = qq[h].front();
                    printf("%d\n", top);
                    qq[h].pop();
                    if (!qq[h].size())
                    {
                        st[ha[top]] = 0;
                        h++;
                    }
                }

            }
        }
        puts("");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值