目录
1.栈
概念
例题(集合栈计算机)
2.队列
概念
例题(团队队列)
3.优先队列
概念
例题(丑数)
栈,是符合“后进先出”(Last In First Out,LIFO)规则规则的数据结构,有PUSH和POP两种操作,其中PUSH把元素压入“栈顶”,而POP从栈顶把元素“弹出。
STL的stack头文件提供了栈,用"stack
问题描述
有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作。
PUSH:空集“{}”入栈。
DUP:把当前栈顶元素复制一份后再入栈。
UNION:出栈两个集合,然会把两者的并集入栈。
INTERSECT:出栈两个集合,然后把二者的交集入栈。
ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。
每次操作后,输出栈顶集合的大小(即元素个数)。例如,栈顶元素是A={{},{{}}},下一个元素是B={{},{{{}}}},则:
UNION操作将得到{{},{{}},{{{}}}},输出3。
INTERSECT操作将得到{{}},输出1。
ADD操作将得到{{},{{{】}},{{},{{}}}},输出3.
输入不超过2000个操作,并且保证操作均能顺利进行(不需要对空栈执行出栈操作)。
示例代码
#include
#include
#include
#include
#include
分析
本题的集合并不是简单的整数集合或者字符串集合,而是集合的集合。为了方便起见,此处为每个不同的集合分配一个唯一的ID,则每个集合都可以表示成所含元素的ID集合,这样就可以用STL的set
来表示了,而整个栈则是一个stack 。
队列是符合“先进先出”(First In Fisrt Out,FIFO)原则的“公平队列”。
STL队列定义在头文件
问题描述
有t个团队的人正在排一个长队。每次新来一个人时,如果他有队友在排队,那么这个新人会插到最后一个队友的身后。如果没有任何一个队友排队,则他会排到长队的队尾。
输入每个团队中所有队员的编号,要求支持如下三种指令(前两种指令可以穿插进行)。
ENQUEUE x:编号为x的人进入长队。
DEQUEUE:长队的队首出队。
STOP:停止模拟。
对于每个DEQUEUE指令,输出出队的人的编号。
示例代码
#include
#include
#include
分析
每个团队有一个队列,而团队整体又形成一个队列。
优先队列是一种抽象数据类型(Abstract Data Type,ADT),行为有些像队列,但先出队列的元素不是先进入队列的元素,而是队列中优先级最高的元素。
STL的优先队列也定义在头文件
自定义类型也可以组成优先队列,但必须为每个元素定义一个优先级。这个优先级并不需要一个确定的数字,只需要能比较大小即可。
STL的queue头文件提供了优先队列,用"priority_queue
问题描述
丑数是指不能被2,3,5以外的其他素数整除的数。把丑数从小到大排列起来,结果如下:
1,2,3,4,5,6,8,9,10,12,14, ....
求第1500个丑数。
示例代码
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int coeff[3] = { 2,3,5 };
int main(){
priority_queue, greater > pq;
set < LL> s;
pq.push(1);
s.insert(1);
for (int i = 1;; i++) {
LL x = pq.top();
pq.pop();
if (i == 1500) {
cout << "The 1500'th ugly number is" << x << ".\n";
break;
}
for (int j = 0; j < 3; j++) {
LL x2 = x*coeff[j];
if (!s.count(x2)) {//如果不存在x2
s.insert(x2);
pq.push(x2);
}
}
}
return 0;
}
分析
从小到大生成各个丑数,最小的丑数是1,而对于任意丑数x,2x,3x,5x也都是丑数。这样可以用一个优先队列保存所有已经生成的丑数,每次取出最小的丑数,生成3个新的丑数。唯一需要注意的是,同一个丑数有多种生成方式,所以需要判断一个丑数是否已经生成过。