算法竞赛常用STL库

栈(Stack)

概念:就像一个盒子一样,进去想出来就得等上面的先出去,也就是“先进后出”。
在这里插入图片描述

往往栈的功能有上面四种,下面我们手写一个栈来实现这四种功能来更好的理解一下。

模拟栈的实现:

#include<iostream>
#include<string>

using namespace std;

const int N = 100010;

int stk[N], tt; //tt为栈顶指针,初始化为0 

int main(){
    
    
	int n; //要进行几次操作 
	cin >> n;
	string op; //要进行的操作
	
	while (n --){
    
    
		cin >> op;
		if (op == "push"){
    
    
			int x; //需要入栈的数 
			cin >> x;
			stk[++ tt] = x;  
		}
		else if (op == "pop") tt --;
		else if (op == "empty") cout << (tt ? "NO" : "YES") << endl;
		else cout << stk[tt] << endl;
	} 
	
	return 0;
} 

模拟栈的实现,只需要控制栈顶指针tt即可。

如果想访问栈顶元素时,只需访问tt所指位置的元素即可。

想往栈添加元素,只需让tt加1,指向下一个位置,然后在该位置存数即可。

想删除栈顶元素,只需让tt减1,这个元素也就不在是栈顶元素,也就是被移出了栈。

判断栈是否为空,只需看tt是否为0即可。

当然比赛中我们直接调用STL库即可。

#include<stack> //头文件

stack<int> s; //定义一个栈

s.size(); //栈中元素的数量 

s.empty(); //栈是否为空 

s.push(); //将此元素压入栈 

s.pop(); //弹出栈顶元素
 
s.top(); //访问栈顶元素 

队列

概念:就像排队一样,先来的人排在前面,后来的人只能排在队尾,先来的人可以先走,后来的人只能后走,也就是“先进先出”。
在这里插入图片描述
往往队列的功能有上面四种,下面我们手写一个队列来实现这四种功能来更好的理解一下。

#include<iostream>
#include<string>

using namespace std;

const int N = 100010;

int q[N];
int hh, tt = -1; //hh为队头,tt为队尾 

int main(){
    
    
	int n; //要进行的操作数 
	cin >> n;
	
	while (n --){
    
    
		string op;
		cin >> op; //要进行的操作
		if (op == "push"){
    
    
			int x; //要加入的数 
			cin >> x;
			q[++ tt] = x; 
		}
		else if (op == "pop") hh ++;
		else if (op == "empty") cout << (hh <= tt ? "NO" : "YES") << endl;
		else cout << q[hh] << endl; 
	}
	
	return 0;
}

模拟队列的实现,只需要控制队头hh和队尾tt即可。

扫描二维码关注公众号,回复: 14815749 查看本文章

如果想查询队头元素,只需查看hh所指地方值即可。

如果想添加一个元素,只需让tt加1,指向下一个位置,在该位置存数即可。

想删除元素,只需让hh加1,让他指向下一个元素,该元素也就删除了。

判断队列是否为空,只需看队头是否大于队尾即可。如果大于队尾则空,反之则不空。

接下来我们看STL库中的队列方法。

#include<queue>

queue<int> q; //定义一个队列

que.size(); //返回队列元素数量

que.empty(); //返回队列是否为空

que.push(); //加入队列

que.pop(); //出队

que.front(); //返回队首

que.back(); //返回队尾 

下面我们来看一道天梯赛L2难度的真题:

例题

一种自动包装机的结构如图 1 所示。首先机器中有 N 条轨道,放置了一些物品。轨道下面有一个筐。当某条轨道的按钮被按下时,活塞向左推动,将轨道尽头的一件物品推落筐中。当 0 号按钮被按下时,机械手将抓取筐顶部的一件物品,放到流水线上。图 2 显示了顺序按下按钮 3、2、3、0、1、2、0 后包装机的状态。
在这里插入图片描述
在这里插入图片描述
一种特殊情况是,因为筐的容量是有限的,当筐已经满了,但仍然有某条轨道的按钮被按下时,系统应强制启动 0 号键,先从筐里抓出一件物品,再将对应轨道的物品推落。此外,如果轨道已经空了,再按对应的按钮不会发生任何事;同样的,如果筐是空的,按 0 号按钮也不会发生任何事。
现给定一系列按钮操作,请你依次列出流水线上的物品。
在这里插入图片描述

分析

通过对题目的分析,我们发现只需要将轨道看成队列,框看成队列,然后模拟这个过程就可以。

代码

#include<iostream>
#include<queue>
#include<stack>

using namespace std;

const int N = 110;

queue<char> q[N]; //轨道
stack<char> s; //筐
int n, m, smax;

int main(){
    
    
	cin >> n >> m >> smax;
	for (int i = 1; i <= n; i ++) 
		for (int j = 0; j < m; j ++){
    
    
			char c;
			cin >> c;
			q[i].push(c);
		}
		
	int x;
	while (cin >> x, x != -1){
    
    
		if (x == 0 && !s.empty()){
    
     //注意需要判断一下是否为空,如果在为空状态下访问栈顶元素会报错
			cout << s.top();
			s.pop();
		}
		if (x > 0 && s.size() < smax && q[x].size()){
    
    
			s.push(q[x].front());
			q[x].pop();
		}
		else if (x > 0 && s.size() >= smax && q[x].size()){
    
    
			cout << s.top();
			s.pop();
			s.push(q[x].front());
			q[x].pop();
		}
	}
	
	return 0;
}

vector

概念:就像一个长度可变的数组一样,把他当成数组处理就可以。

STL库:

#include<vector>

vector<int> v; //定义一个vector

v.push_back(item); //向v后加一个元素

v.pop_back(); //删除v最后一个元素

v.size(); //获取v中元素个数

v.empty(); //判断v是否为空

v.clear(); //清空v中的元素

v[index]; //获取v中下标为index的元素O(1)

v.begin(); //返回指向第一个元素的迭代器

v.end(); //返回指向vector末尾(最后一个元素之后的那个位置)的迭代器

v.front(); //返回第一个元素

v.back(); //返回最后一个元素

set

概念:相当于是数学的集合,会对相同的元素进行去重处理并默认排序。

STL库:

#include<set>

set<int>s; //定义一个set

s.insert(); //插入一个元素 

s.size(); //获取元素的个数

s.empty(); //判断是否为空

s.clear(); //清空s

s.count(item); //返回s中item的数量,因为集合中的元素不能重复,因此只能返回0或1 

map

概念:map是一个键值对,是一个映射关系,你可以理解为帮你封装好了的hash表,通过键访问你的值。

STL库:

#include<map>

map<int,int> mp; //定义一个map

mp.size(); //获取元素个数

mp.empty(); //判断是否为空

mp.clear(); //清空mp

mp[key]=tmp; //可以把键值对key—value中的value赋值为tmp,如果没有对应的键值对,则将该键值对插入到map中

猜你喜欢

转载自blog.csdn.net/weixin_51711289/article/details/129752549