题目链接:
http://poj.org/problem?id=2259
题目大意:
告诉你一堆人(m个人是一组的,n个人是一组的。。。。);然后一个人来排队了,先看下有自己组的熟人吗?有的话直接排在自己组的人的队尾(呵呵,是不是现实中有这样的),没有熟人的话直接排队尾咯。
题目给定进队和出队命令,求解出队的顺序。
思路:
- 每个组需要有一个队列
queue<int> team[teamIndex]
- 每个组需要一个标记,我们组是否有人 true,false
bool teamInQueue[teamIndex]
- 每个人与组号之间的映射
people[peopleID]=teamIndex
- 如果组的标记为 true,再把组的序号存成大的队列
queue<int> mainQueue
- 入队:检查人ID是哪个组的;check组号的标记,知道组是否在大队 mainQueue里,true,则在该组入队,false,则把自己组的标记改成 true,并把自己的组号压入大队 mainQueue里,并且自己入队该组
- 出队:找到 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 1000000queue<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;
}