队列
(本文仅为笔者学习笔记,如有错误之处恳请各位读者指正)
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
3 | 9 | 2 | 4 |
初始队列
9 | 2 | 4 |
9 | 2 | 4 | 7 |
常用方法:
- push(x): 元素x入队列。
- pop(): 弹出队首元素。
- front(): 获取队首元素。
- empty(): 判断队列是否为空。
例:
简译:有t个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么这个新人会插队到最后一个队友的身后。如果没有任何一个队友排队,则他会排到长队的队尾。
输入每个团队中所有队员的编号,要求支持如下3种指令(前两种指令可穿插进行)。
- ENQUEUE x: 编号为x的人进入长队。
- DEQUEUE: 长队的队首出队。
- STOP: 停止模拟。
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
const int maxt = 1000+10;
int main(){
int t, kase = 0;
while(scanf("%d",&t)==1 && t){ // 对队伍数有输入&&队伍数不为0
printf("Scenario #%d\n", ++kase);
// 记录所有人的团队编号
map<int, int> team; // team[x]表示为x的人所在的队伍编号
for(int i=0; i<t ; i++){
int n ,x;
scanf("%d", &n); // 输入每个队伍的总人数
while(n--){
scanf("%d", &x); // 输入每个人的编号
team[x] = i; // 为每个人分配队伍,i:队伍编号
}
}
// 模拟
queue<int> q, q2[maxt]; // q是整个长队的队列(记录每个队伍的编号) ,q2[i]是队伍i的成员队列
while(true){
int x;
char cmd[10];
scanf("%s", cmd); // 输入命令
if(cmd[0] == 'S') // 停止模拟命令
break;
else if(cmd[0] == 'D'){ // 出队列命令
int t = q.front(); // 获取整个长队的队首队伍编号
printf("%d\n", q2[t].front()); // 输出该队伍的队首成员编号
q2[t].pop(); // 该队伍的队首出队
if(q2[t].empty()) // 处于整个长队队首的队列为空,则该队列(编号)出整个长队
q.pop();
}else if(cmd[0] == 'E'){ // 入队列命令
scanf("%d", &x);
int t = team[x]; // 获取编号为x的成员所在的队伍编号
if(q2[t].empty()) // 该队伍不在整个长队内
q.push(t); // 队伍(编号)入整个长队的队尾
q2[t].push(x); // 成员x入队伍t的队列队尾(最后一个队友的身后)
}
}
printf("\n");
}
return 0;
}
题目链接:
Team Queue - UVa 540