POJ 2259 team queue团队排队问题

题目链接:
http://poj.org/problem?id=2259

题目大意:

告诉你一堆人(m个人是一组的,n个人是一组的。。。。);然后一个人来排队了,先看下有自己组的熟人吗?有的话直接排在自己组的人的队尾(呵呵,是不是现实中有这样的),没有熟人的话直接排队尾咯。
题目给定进队和出队命令,求解出队的顺序。
在这里插入图片描述

思路:

  1. 每个组需要有一个队列 queue<int> team[teamIndex]
  2. 每个组需要一个标记,我们组是否有人 true,false bool teamInQueue[teamIndex]
  3. 每个人与组号之间的映射 people[peopleID]=teamIndex
  4. 如果组的标记为 true,再把组的序号存成大的队列 queue<int> mainQueue
  5. 入队:检查人ID是哪个组的;check组号的标记,知道组是否在大队 mainQueue里,true,则在该组入队,false,则把自己组的标记改成 true,并把自己的组号压入大队 mainQueue里,并且自己入队该组
  6. 出队:找到 mainQueue里的 front是哪个组的组号,从该组打印ID并出队;检查该组还有人吗,如果没人了,把该组组号从 mainQueue里出队,并把该组的标记改成false

Accepted 代码如下:

/**
 * @description: poj2259 团队排队问题
 * @author: michael ming
 * @date: 2019/4/5 11:24
 * @modified by: 
 */
#include <iostream>
#include <queue>
#include <string>
using namespace std;
#define MAX 1000
#define MAX_PEOPLE 1000000

queue<int> team[MAX]; //team[i]代表一个组队列
queue<int> mainQueue;   //宏观主队列,存储teamIndex值
bool teamInQueue[MAX];  //队伍是否排在主队列中
int people[MAX_PEOPLE]; //存储人的队伍teamIndex编号
int teamNums, Scenario=1;
void init()  //每次进入下一次任务时,清空前一次的记录
{
    for(int i = 0; i < teamNums; ++i)  //队列清空
    {
        teamInQueue[i] = false;
        while(!team[i].empty())
            team[i].pop();
    }
    while(!mainQueue.empty())
        mainQueue.pop();
}
void input()    //输入人员信息,及记录每人的组号
{
    int totalPeopleInTeam,peopleID;
    for(int teamIndex = 0; teamIndex < teamNums; ++teamIndex)
    {
        cin >> totalPeopleInTeam;
        for(int j = 0; j < totalPeopleInTeam; ++j)
        {
            cin >> peopleID;
            people[peopleID] = teamIndex;
            //把每个人的ID(数组中的位置)与其值(组号)建立映射
        }
    }
}
void solve()
{
    int peopleID,teamID;
    string command;
    cout << "Scenario #" << Scenario++ << endl;
    while(cin >> command && command[0] != 'S')  //STOP停止
    {
        if (command[0] == 'E')  //ENQUEUE入队
        {
            cin >> peopleID;  //输入ID后查询其组号teamID(即people[peopleID])
            teamID = people[peopleID];
            if(teamInQueue[teamID]) //组号是否在大队列里呢(初始为false不在)
            {
                team[teamID].push(peopleID);  //找到我的组入组
            }
            else    //我组没人,我是第一个
            {
                teamInQueue[teamID] = true; //我们组终于有人了
                mainQueue.push(teamID);     //我们组的组号排在最后一组
                team[teamID].push(peopleID);  //找到我的组入组
            }
        }
        else   //DEQUEUE出队
        {
            if(!mainQueue.empty())  //大团组必须还有,如果无,则完全没人了
            {
                teamID = mainQueue.front();   //队头是哪个组的呀
                cout << team[teamID].front() << endl; //从相应的组里找到该组的头
                team[teamID].pop();  	 //打印了,出队
                if(team[teamID].empty())  //这个组空了,都出去了
                {
                    teamInQueue[teamID] = false;  //标记一下
                    mainQueue.pop();    //从大队里删除空组
                }
            }
        }
    }
    cout << endl;
}
int main()
{
    while(cin >> teamNums && teamNums)
    {
        init(); 	//初始化组的标记,及清空队列
        input();    //输入人员ID,记录人员组号
        solve();    //队列出队,入队操作
    }
    return 0;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michael阿明

如果可以,请点赞留言支持我哦!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值