蓝桥备赛指南(5)

queue队列

queue是一种先进先出的数据结构。它提供了一组函数来操作和访问元素,但它的功能相对较简单,queue函数的内部实现了底层容器来存储元素,并且只能通过特定的函数来访问和操作元素。

queue函数的常用函数

1.push()函数: 在队尾插入元素;

2.pop() 函数:弹出队首元素;

3.front() 函数: 返回队首元素;

4.back()函数:返回队尾元素;

5.empty()函数:检查队列是否为空;

6.size()函数:返回队列元素的个数

priority_queue优先队列

priority_queue函数与普通队列不同,priority_queue函数中的元素是按照一定的优先级进行排序的。默认情况下,priority_queue按照元素的大小的值由大到小进行排序的,即top()一定是最大的。priority_queue的内部实现了使用底层容器来存储元素,并且只能通过特定的函数来访问和操作元素。

priority_queue函数的常用函数

1.push()函数:将元素插入到优先队列中;

2.pop()函数:退回优先队列中的顶部元素

3.top()函数:返回优先队列中的顶部元素

4.empty()函数:检查优先队列是否为空

5.size()函数:返回优先队列中元素的个数

优先队列修改比较函数的方法

示例1:

struct Compare {
	bool operator()(int a, int b) {
		return a > b;
	}
};

int main() {
	std::priority_queue<int, std::vector<int>, Compare> pq;
	return 0;
}

示例2:

auto Compare = [](int a, int b) {
	return a > b;
	};
std::priority_queue<int, std::vector<int>, decltype(compare)> pq(compare);

注意:如果优先队列比较简单,可以直接使用greater<T>来修改比较方法。

priority_queueint,vector<int>,greater<int>> pq;

std::greater函数对象定义在<functional>头文件中。

deque双端队列

deque是一种容器,它允许在两端进行高效的插入和删除操作。deque是由一系列连续的存储块(缓冲区)组成的,每个存储块都存储了多个元素,这deque函数能够在两端快速的插入和删除操作,而不需要移动其他元素。

deque函数的常用函数

1.push_back()函数:在尾部插入元素;

2.push_front()函数:在头部插入元素;

3.pop_back()函数:弹出尾部元素;

4.front()函数:返回头部元素;

5.back()函数;返回尾部元素;

6.empty()函数:检查deque是否为空

7.size()函数:返回deque中的元素个数;

8.clear()函数:清空deque中的所有元素

例题讲解

题目一:

CLZ银行问题

题目描述

CLZCLZ 银行只有两个接待窗口,VIPVIP 窗口和普通窗口,VIPVIP 用户进入 VIPVIP 窗口排队,剩下的进入普通窗口排队。现有 MM 次操作,操作有四种类型,如下:

  • IN name V:表示一名叫 name 的用户到 VIPVIP 窗口排队
  • OUT V:表示 VIPVIP 窗口队头的用户离开排队
  • IN name N:表示一名叫 name 的用户到普通窗口排队
  • OUT N:表示普通窗口队头的用户离开排队

求 MM 次操作结束后 VIPVIP 窗口队列和普通窗口队列中的姓名。

输入描述

第一行是一个整数 M(1≤M≤1000)M(1≤M≤1000),表示一共有 MM 次操作。

第二行到第 M+1M+1 行输入操作,格式如下:

  • IN name V
  • OUT V
  • IN name N
  • OUT N

输出描述

输出 MM 次操作后 VIPVIP 窗口队列和普通窗口队列中的姓名(从头到尾),先输出 VIPVIP 窗口队列后输出普通窗口队列。

输入输出样例

示例 1

输入

5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V

输出

Adel
CLZ
laozhao

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题解:

#include<iostream>
#include<algorithm>
#include<vector>
int mian() {
	//输入输出同步流
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	//输入M
	int M; cin >> M;
	queue<string> V, N;
	//遍历
	while (M--) {
		//输入op:op=IN表示用户到窗口排队
		string op; cin >> op;
		//判断op是否等于IN
		if (op == "IN") {
			//输入nmae,表示用户姓名
			//输入q:q=V表示用户到VIP窗口排队
			string name,q; cin >> name >> q;
			//判断q是否等于V
			if (q == "V") V.push();//如果q==V,则在name之后插入元素v
			else N.push();//否则其判断对象就为N
		}
		//如果q不等于与IN
		else {
			//输入q:q=V表示用户到VIP窗口排队
			string q; cin >> q;
			//判断q是否等于V
			if (q == "V") V.pop();//如果q!=V,则弹出队首元素
			else N.pop();//否则其判断对象就为N
		}
	}
	//遍历
	while (V.size()) {//定义原始数组大小
		//输出队首元素
		cout << V.front() << endl;
		//弹出队首元素
		V.pop;
	}
	//同理
	while (N.size()) {
		cout << N.front() << endl;
		N.pop();
	}
	return 0;
}

题目二:

合并果子

题目描述

在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。

每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过 n−1n−1 次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为 11,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

例如有 33 种果子,数目依次为 1,2,91,2,9。可以先将 1、21、2 堆合并,新堆数目为 33,耗费体力为 33。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为 1212,耗费体力为 1212。所以多多总共耗费体力 =3+12=15=3+12=15。可以证明 1515 为最小的体力耗费值。

输入描述

输入两行。

第一行是一个整数 n(1≤n≤104)n(1≤n≤104),表示果子的种类数。

第二行包含 nn 个整数,用空格分隔,第 ii 个整数 ai(1≤ai≤2×104)ai​(1≤ai​≤2×104) 是第 ii 种果子的数目。

输出描述

输出一个整数,也就是最小的体力耗费值。输入数据保证这个值小于 231231。

输入输出样例

示例 1

输入

3 
1 2 9 

输出

15 

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题解:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
using ll = long long;
int main() {
	//同步流
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	//水果种类数
	ll n; cin >> n;
	priority_queue < ll, vector<ll>, greater<ll>> pq;
	for (int i = 1; i <= n; i++) {
		//每种果子的数目
		ll x; cin >> x;
		pq.push(x);
	}
	ll ans = 0;
	while (pq.size() >= 2) {
		ll x = pq.top(); pq.pop();
		ll y = pq.top(); pq.pop();
		ans += x + y;
		pq.push(x + y);
	}
	cout << ans << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值