Day 5 知识点:STL-stack,queue,priority_queue,深搜,数学知识

STL

stack

栈,特点是 FILO(先进后出),像单口的羽毛球桶,羽毛球如数据一般,最后被放入的羽毛球会被第一个提取,倒数第二个放入的羽毛球会被第二个提取。

image

【定义方法】:
stack<数据类型> 栈容器名;

【相关函数】:

  1. 入栈 push(数据); 将数据放入栈
  2. 栈顶 top(); 返回栈顶的数据-非空才可以操作
  3. 出栈 pop(); 将栈顶元素出栈-非空才可以操作
  4. 大小 size(); 返回栈内数据个数
  5. 空栈 empty(); 如果栈内没有数据,返回为 true

queue

队列,特点是 FIFO(先进先出),就好比排的队伍,先入队伍的优先出队。

image

【定义方法】:
queue<数据类型> 队列容器名;

【相关函数】:

  1. 入队 push(数据); 将数据放入队列中
  2. 队首 front(); 返回队首数据
  3. 队尾 back(); 返回队尾数据
  4. 出队 pop(); 删除队首数据
  5. 大小 size(); 返回队列的数据个数
  6. 空队 empty(); 如果是空队,返回 true

priority_queue

优先队列,会根据队列中的数据按优先级进行排序,先提取最高优先级。
默认情况以数据类型数值越大优先级越大。

【定义方法】:
priority_queue<数据类型> 优先队列容器名;

【相关函数】:

  1. 入队 push(数据); 将数据放入优先队列中
  2. 队首 top(); 返回队首数据
  3. 出队 pop(); 删除队首数据
  4. 大小 size(); 返回优先队列的数据个数
  5. 空队 empty(); 如果是空队,返回 true

【优先队列对结构体进行排序】

// 优先队列对结构体进行自定义优先级
struct peo {
	string name;	// 姓名
	int id;			// 学号
	double score;	// 分数
	
	// 分数越高 优先级越大,如果分数相等 学号小的 优先级越大 
	// step 1. 在结构体中写标准模板
	// step 2. 添加同一个 b 变量 和 cmp 一致
	// step 3. cmp 填写规则 关于添加的b. 删除
	// 标准模板 bool operator < (const 结构体类型 &a) const { ... }
	bool operator < (const peo &a) const {
		if (a.score != score) return a.score > score;
		return a.id < id;
	}
};

priority_queue<peo> q;

int main() {
	// 输入三个人的姓名和学号和分数
	for (int i = 1; i <= 3; i++) {
		peo a;
		cin >> a.name >> a.id >> a.score;
		q.push(a);
	}
	while (!q.empty()) {
		peo a = q.top();
		q.pop();
		cout << a.name << "\n";
	}
	return 0;
}

深搜

深度优先搜索(Depth First Search)。

实际上是将所有的情况进行一一列举,典型的运用是在走迷宫上。

考虑起点 (x,y) ,判断在起点 (x,y) 能否走到终点,首先确保不重不漏的搜索方向,向四周相邻点进行扩散,这里的四周相邻点可以运用方向数组代替,在判断方向时可以使用循环来减少代码量。

【方向数组】
根据当前 x,y 的所在位置,那么四周相邻的点可以根据偏移量得到。

image

可以用二维数组保存,也可以使用两个一维数组保存。

深搜逻辑:

image

#include <bits/stdc++.h>
using namespace std;

char g[45][45];			// 地图 g 二维数组
bool vis[45][45];		// vis true 表示这个位置是否走过
int f[4][2]{-1, 0, 1, 0, 0, 1, 0, -1}; // 方向数组
// 第一个方向上 f[0][0] 是 x 的变化,f[0][1] 是 y 的变化 
int n, m;
bool ok = false;		// true 标记能否走到终点 

// dfs 从 (x,y) 能不能走到终点 
void dfs(int x, int y) {
	if (x == n && y == m) {		// 边界条件 
		ok = true;				// 说明已经找到了终点 
		return ;
	}
	
	for (int i = 0; i < 4; i++) {	// 把四个相邻的方向全部判断 
		int nx, ny;
		nx = x + f[i][0];			// x 坐标变成 nx 利用方向数组第 i 个方向偏移量
		ny = y + f[i][1];			// y 坐标变成 ny 利用方向数组第 i 个方向偏移量
		
		// 下一个位置是 走过的、墙壁、超出地图的位置  跳过这个方向
		if (nx < 1 || nx > n || ny < 1 || ny > m || vis[nx][ny] || g[nx][ny] == '#') continue;
		// 可以走的路
		vis[nx][ny] = true;			// 下一个位置标记为 true  代表已经走过 
		dfs(nx, ny);				// 继续从新的位置开始走 
	} 
	
}

int main() {
	cin >> n >> m;		// 输入保存在 g 二维地图中 
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> g[i][j];
		}
	}
	vis[1][1] = true;		// 起点标记已经走过
	dfs(1, 1);				// depth first search 深度优先搜索 
	if (ok) cout << "YES";
	else cout << "NO";
	return 0;
}

深度优先搜索也可以适用于其他场景,需要用标记数组标记已经选择过的,每次的选择应该如何操作,完成递归式与递归边界条件即可。

数学基础

欧式距离

也是直线距离

image

曼哈顿距离

image

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值