STL
stack
栈,特点是 FILO(先进后出),像单口的羽毛球桶,羽毛球如数据一般,最后被放入的羽毛球会被第一个提取,倒数第二个放入的羽毛球会被第二个提取。
【定义方法】:
stack<数据类型> 栈容器名;
【相关函数】:
- 入栈 push(数据); 将数据放入栈
- 栈顶 top(); 返回栈顶的数据-非空才可以操作
- 出栈 pop(); 将栈顶元素出栈-非空才可以操作
- 大小 size(); 返回栈内数据个数
- 空栈 empty(); 如果栈内没有数据,返回为 true
queue
队列,特点是 FIFO(先进先出),就好比排的队伍,先入队伍的优先出队。
【定义方法】:
queue<数据类型> 队列容器名;
【相关函数】:
- 入队 push(数据); 将数据放入队列中
- 队首 front(); 返回队首数据
- 队尾 back(); 返回队尾数据
- 出队 pop(); 删除队首数据
- 大小 size(); 返回队列的数据个数
- 空队 empty(); 如果是空队,返回 true
priority_queue
优先队列,会根据队列中的数据按优先级进行排序,先提取最高优先级。
默认情况以数据类型数值越大优先级越大。
【定义方法】:
priority_queue<数据类型> 优先队列容器名;
【相关函数】:
- 入队 push(数据); 将数据放入优先队列中
- 队首 top(); 返回队首数据
- 出队 pop(); 删除队首数据
- 大小 size(); 返回优先队列的数据个数
- 空队 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 的所在位置,那么四周相邻的点可以根据偏移量得到。
可以用二维数组保存,也可以使用两个一维数组保存。
深搜逻辑:
#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;
}
深度优先搜索也可以适用于其他场景,需要用标记数组标记已经选择过的,每次的选择应该如何操作,完成递归式与递归边界条件即可。
数学基础
欧式距离
也是直线距离