在c++中大家都爱着STL容器和函数今天我们就来介绍一下队列这个容器
废话不多说开始正题:
1.queue 队列容器 是 先进先出 ( FIFO , First In First Out ) 容器 ;
该容器只允许在 " 队尾 " 进行插入操作 , 而在 " 队首 " 进行删除操作 ;
该容器两边开口 , 一边用于插入元素 ( 不能删除 ) , 一边用于删除元素 ( 不能插入 ) ;
stack 堆栈容器 是 一边开口 , 也就是 栈顶开口 , 栈顶可以 添加 / 删除 元素 , 栈底 不能进行操作 ;
2、queue 队列容器特点
queue 队列容器 的 插入 / 删除 元素操作 时间复杂度是 O(1) ;
queue 队列容器 提供的 api 成员函数 与 stack 堆栈容器 类似 , 只提供有限的成员函数 , 如 :
queue#push 函数 : 队尾 插入元素 ;
queue#pop 函数 : 队首 删除元素 ;
queue#front 函数 : 查看 队首元素;
非常符合一些题目的性质比如下面这一题:
题目描述
小可家里有一个大饭店,每天都生意兴隆以至于去这个饭店吃饭需要取号排队,现在小可想了解饭店内顾客排队的情况。
输入格式
输入多行
每行都有一个英文单词
若英文单词为wait
,则表示有顾客在等待取餐,后面会再输入一个整数,表示这个顾客取的号是多少
若英文单词为ok
,则表示顾客取到餐离开
若英文单词为END
,则表示输入结束
输出格式
输出多行
每当有顾客取到餐离开时,输出该顾客的号码,若无人等待则输出none
。
输入数据 1
ok
wait 1
wait 2
ok
wait 3
ok
ok
ok
END
Copy
输出数据 1
none
1
2
3
none
Copy
数据范围与约定
对于 100%100% 的数据:输入数据不超过100行
这个非常符合STL中队列的特点
思路:
- 先定义一个队列a(用STL就行)
- 然后while(true)死循环
- 定义一个string,叫s
- 输入s
- 判断s是否等于"wait",如果是,就定义整数n, 输入n,把n压入a
- 判断s是否等于"ok",如果是,就先判空(a),如果为空,就输出"none";否则输出队首,弹出队首
- 判断s是否等于"END",如果是,结束循环
代码如下:
#include <bits/stdc++.h>
using namespace std;
queue<int> a;
int main(){
while(true){
string s;
cin >> s;
if(s == "wait"){
int n;
cin >> n;
a.push(n);
}else if(s == "ok"){
if(a.empty()) cout << "none" << endl;
else{
cout << a.front() << endl;
a.pop();
}
}else if(s == "END"){
break;
}
}
return 0;
}
这些都是STL中队列的基本操作
3.优先队列
priority_queue
这是一个非常方便的容器具体方便在哪呢:他是从大到小排序的定义方法还是和queue一样当然也可以使用从小到大排序定义方法如下
priority_queue<int,vector<int>,greater<int> > h;
这种对了放在实战中也非常好用题目如下
[NOIP2004提高组] 合并果子
问题描述
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的可以看出,所有的果子经过n−1n−1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗 的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假 定每个果子重量都为11,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并 的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有33种果子,数目依次为1,2,91,2,9。可以先将1、21、2堆合并,新堆数目为33,耗费体力为33。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为1212,耗费体力为1212。 所以多多总共耗费体力3+12=153+12=15。可以证明1515为最小的体力耗费值。
输入格式
输入包括两行,第一行是一个整数n(1≤n≤30000)n(1≤n≤30000),表示果子的种类数。
第二行包含nn个整数,用空格分隔,第i个整数ai(1≤ai≤20000)ai(1≤ai≤20000)是第i种果子的数目。
输出格式
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输 入数据保证这个值小于231231。
输入数据 1
3
1 2 9
Copy
输出数据 1
15
Copy
输入数据 2
10
3 5 1 7 6 4 2 5 4 1
Copy
输出数据 2
120
Copy
数据范围与约定
对于 30%的数据,保证有 n≤1000n≤1000;
对于 50%的数据,保证有n≤5000n≤5000;
对于全部的数据,保证有n≤10000n≤10000。
这道题是NOIP的题目 不难发现是一道贪心问题 配合上优先队列效果更佳
思路如下:
用优先队列把数据放进来
默认从大到小排序使用第二种第二种定义方法
最后模拟体力消耗即可代码如下
#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int>,greater<int> > h;
int n;
int ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
h.push(x);
}
while(h.size()>1){
int a = h.top();
h.pop();
int b = h.top();
h.pop();
ans+=a+b;
h.push(a+b);
}
cout << ans;
}
这就是队列 给个赞把!