题意:有n个队伍。 对于每个ENQUEUE x 命令。 如果x所在的队伍已经在队列中, 则x排在队列中它的队伍的尾巴, 否则排在队列的末尾。 可以理解为队列中的队列的味道。
思路:用一个team[]数组, 来标记所有数字所在的队列。 queue<int> que[1000], 由于组数最多有1000组, 也就是最多有1000个子队列, 如果你在第0组, 把你放到大队列中, 只要把你放到que[0].push(你), 如果在你之前, que[0].empty(), 那么 需要 bigQue.push(0), 这样你所在组的队列也就在大队列里了。 对于DEQUEUE命名, 只需要front_team = bigQue.front() 得到排在最前面的组的编号, 然后在 que[front_team].front() 就可以得出大队列的队首, 然后要判断这个que[front_team].empty(), 如果空了 就要pop出去。
算法复杂度: 输入o(M) + 命令操作o(N)。 M最大1,000,000。 N 最大200,000。 小伙伴们, 这下我凌乱了。 感觉不知道算哪一个。
代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define MAX_RANK 1000000
#define MAX_QUE 1000
#define MAX_N 1000
#define CMD_CHAR 30
int team[MAX_RANK];
queue<int> que[MAX_QUE];
queue<int> bigQue;
void init();
int main()
{
int cases = 1;
int teamM;
while (scanf("%d", &teamM) == 1 && teamM) {
// init
init();
// enter team
int n;
memset(team, 0, sizeof(team));
for (int team_NO = 0; scanf("%d", &n) == 1; team_NO++) {
for (int i = 0; i < n; i++) {
int num;
scanf("%d%*c", &num);
team[num] = team_NO;
}
}
// read commands
printf("Scenario #%d\n", cases++);
while (true) {
char cmd[CMD_CHAR];
scanf("%s", cmd);
if (strcmp(cmd, "ENQUEUE") == 0) {
int num;
scanf("%d%*c", &num);
if (que[team[num]].empty()) {
bigQue.push(team[num]);
}
que[team[num]].push(num);
} else if (strcmp(cmd, "DEQUEUE") == 0) {
int whitch_team = bigQue.front();
printf("%d\n", que[whitch_team].front());
que[whitch_team].pop();
if (que[whitch_team].empty()) {
bigQue.pop();
}
} else {
printf("\n");
break;
}
}
}
return 0;
}
void init()
{
while (!bigQue.empty()) {
bigQue.pop();
}
for (int i = 0; i < MAX_QUE; i++) {
while (!que[i].empty()) {
que[i].pop();
}
}
}