LeetCode BFS解决最短路问题

广度优先搜索(BFS, Breadth-First Search)是一种用于图和树结构的遍历算法,特别适合解决无权图的最短路径问题

算法思想

BFS从起始节点开始,按照"广度优先"的原则,逐层向外扩展搜索:

  1. 先访问起始节点的所有相邻节点(第一层)。
  2. 然后访问这些相邻节点的相邻节点(第二层)。
  3. 依此类推,直到找到目标节点或遍历完整个图。

BFS最短路径算法步骤

  1. 初始化
    • 创建队列,放入起始节点。
    • 记录每个节点的访问状态和距离(起始节点距离为0)。
  2. 循环处理队列
    • 取出队首节点。
    • 遍历其所有未访问的邻居节点。
    • 记录这些邻居的距离(当前节点距离+1)。
    • 将邻居节点加入队列。
  3. 终止条件
    • 找到目标节点时返回其距离。
    • 队列为空时表示无法到达。

中等

433. 最小基因变化

基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 'A''C''G''T' 之一。

假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。

  • 例如,"AACCGGTT" --> "AACCGGTA" 就是一次基因变化。

另有一个基因库 bank 记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。(变化后的基因必须位于基因库 bank 中)

给你两个基因序列 startend ,以及一个基因库 bank ,请你找出并返回能够使 start 变化为 end 所需的最少变化次数。如果无法完成此基因变化,返回 -1

注意:起始基因序列 start 默认是有效的,但是它并不一定会出现在基因库中。

示例 1:

输入:start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"]
输出:1

示例 2:

输入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"]
输出:2

示例 3:

输入:start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"]
输出:3

提示:

  • start.length == 8
  • end.length == 8
  • 0 <= bank.length <= 10
  • bank[i].length == 8
  • startendbank[i] 仅由字符 ['A', 'C', 'G', 'T'] 组成
int minMutation(string startGene, string endGene, vector<string>& bank) {if (startGene == endGene) {return 0;}unordered_set<string> vis;unordered_set<string> hash(bank.begin(), bank.end());const string change = "ACGT";queue<string> que;que.push(startGene);hash.insert(startGene);int step = 0;while (!que.empty()) {step++;int n = que.size();while (n--) {string str = que.front();que.pop();for (int i = 0; i < 8; ++i) {string tmp = str;for (int j = 0; j < 4; ++j) {tmp[i] = change[j];if (hash.count(tmp) && !vis.count(tmp)) {if (tmp == endGene) {return step;}vis.insert(tmp);que.push(tmp);}}}}}return -1;
}

542. 01 矩阵

给定一个由 01 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。

两个相邻元素间的距离为 1

示例 1:

img
输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]

示例 2:

img
输入:mat = [[0,0,0],[0,1,0],[1,1,1]]
输出:[[0,0,0],[0,1,0],[1,2,1]]

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 104
  • 1 <= m * n <= 104
  • mat[i][j] is either 0 or 1.
  • mat 中至少有一个 0
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {// 正难则反// 把0当作起点,1当作终点int m = mat.size(), n = mat[0].size();vector<vector<bool>> vis(m, vector<bool>(n, false));queue<pair<int, int>> que;for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (mat[i][j] == 0) {que.emplace(i, j);vis[i][j] = true;}}}vector<vector<int>> ans(mat);int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny]) {vis[nx][ny] = true;ans[nx][ny] = step;que.emplace(nx, ny);}}}}return ans;
}

优化

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {// 正难则反// 把0当作起点,1当作终点int m = mat.size(), n = mat[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));queue<pair<int, int>> que;for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (mat[i][j] == 0) {que.emplace(i, j);dist[i][j] = 0;}}}while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && dist[nx][ny] == -1) {dist[nx][ny] = dist[x][y] + 1;que.emplace(nx, ny);}}}return dist;
}

1162. 地图分析

你现在手里有一份大小为 n x n 的 网格 grid,上面的每个 单元格 都用 01 标记好了。其中 0 代表海洋,1 代表陆地。

请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的,并返回该距离。如果网格上只有陆地或者海洋,请返回 -1

我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0)(x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1|

示例 1:

img

输入:grid = [[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释: 
海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。

示例 2:

img

输入:grid = [[1,0,0],[0,0,0],[0,0,0]]
输出:4
解释: 
海洋单元格 (2, 2) 和所有陆地单元格之间的距离都达到最大,最大距离为 4。

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 100
  • grid[i][j] 不是 0 就是 1
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {1, -1, 0, 0};int maxDistance(vector<vector<int>>& grid) {queue<pair<int, int>> que;int m = grid.size(), n = grid[0].size();vector<vector<int>> dist(m, vector<int>(n, -1));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (grid[i][j] == 1) {que.emplace(i, j);dist[i][j] = 0;}}}int ans = -1;while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && dist[nx][ny] == -1) {dist[nx][ny] = dist[x][y] + 1;ans = max(ans, dist[nx][ny]);que.emplace(nx, ny);}}}return ans;
}

1765. 地图中的最高点

给你一个大小为 m x n 的整数矩阵 isWater ,它代表了一个由 陆地水域 单元格组成的地图。

  • 如果 isWater[i][j] == 0 ,格子 (i, j) 是一个 陆地 格子。
  • 如果 isWater[i][j] == 1 ,格子 (i, j) 是一个 水域 格子。

你需要按照如下规则给每个单元格安排高度:

  • 每个格子的高度都必须是非负的。
  • 如果一个格子是 水域 ,那么它的高度必须为 0
  • 任意相邻的格子高度差 至多1 。当两个格子在正东、南、西、北方向上相互紧挨着,就称它们为相邻的格子。(也就是说它们有一条公共边)

找到一种安排高度的方案,使得矩阵中的最高高度值 最大

请你返回一个大小为 m x n 的整数矩阵 height ,其中 height[i][j] 是格子 (i, j) 的高度。如果有多种解法,请返回 任意一个

示例 1:

img

输入:isWater = [[0,1],[0,0]]
输出:[[1,0],[2,1]]
解释:上图展示了给各个格子安排的高度。
蓝色格子是水域格,绿色格子是陆地格。

示例 2:

img

输入:isWater = [[0,0,1],[1,0,0],[0,0,0]]
输出:[[1,1,0],[0,1,1],[1,2,2]]
解释:所有安排方案中,最高可行高度为 2 。
任意安排方案中,只要最高高度为 2 且符合上述规则的,都为可行方案。

提示:

  • m == isWater.length
  • n == isWater[i].length
  • 1 <= m, n <= 1000
  • isWater[i][j] 要么是 0 ,要么是 1
  • 至少有 1 个水域格子。

**注意:**本题与 542 题相同。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};vector<vector<int>> highestPeak(vector<vector<int>>& isWater) {queue<pair<int, int>> que;int m = isWater.size(), n = isWater[0].size();vector<vector<int>> ans(m, vector<int>(n, -1));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (isWater[i][j] == 1) {que.emplace(i, j);ans[i][j] = 0;}}}while (!que.empty()) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && ans[nx][ny] == -1) {ans[nx][ny] = ans[x][y] + 1;que.emplace(nx, ny);}}}return ans;
}

1926. 迷宫中离入口最近的出口

给你一个 m x n 的迷宫矩阵 maze下标从 0 开始),矩阵中有空格子(用 '.' 表示)和墙(用 '+' 表示)。同时给你迷宫的入口 entrance ,用 entrance = [entrancerow, entrancecol] 表示你一开始所在格子的行和列。

每一步操作,你可以往 或者 移动一个格子。你不能进入墙所在的格子,你也不能离开迷宫。你的目标是找到离 entrance 最近 的出口。出口 的含义是 maze 边界 上的 空格子entrance 格子 不算 出口。

请你返回从 entrance 到最近出口的最短路径的 步数 ,如果不存在这样的路径,请你返回 -1

示例 1:

img
输入:maze = [["+","+",".","+"],[".",".",".","+"],["+","+","+","."]], entrance = [1,2]
输出:1
解释:总共有 3 个出口,分别位于 (1,0),(0,2) 和 (2,3) 。
一开始,你在入口格子 (1,2) 处。
- 你可以往左移动 2 步到达 (1,0) 。
- 你可以往上移动 1 步到达 (0,2) 。
从入口处没法到达 (2,3) 。
所以,最近的出口是 (0,2) ,距离为 1 步。

示例 2:

img
输入:maze = [["+","+","+"],[".",".","."],["+","+","+"]], entrance = [1,0]
输出:2
解释:迷宫中只有 1 个出口,在 (1,2) 处。
(1,0) 不算出口,因为它是入口格子。
初始时,你在入口与格子 (1,0) 处。
- 你可以往右移动 2 步到达 (1,2) 处。
所以,最近的出口为 (1,2) ,距离为 2 步。

示例 3:

img
输入:maze = [[".","+"]], entrance = [0,0]
输出:-1
解释:这个迷宫中没有出口。

提示:

  • maze.length == m
  • maze[i].length == n
  • 1 <= m, n <= 100
  • maze[i][j] 要么是 '.' ,要么是 '+'
  • entrance.length == 2
  • 0 <= entrancerow < m
  • 0 <= entrancecol < n
  • entrance 一定是空格子。

BFS层序遍历,每次step++,第一次到达边界时就是最短路径,vis数组判断是否访问过该节点。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};int nearestExit(vector<vector<char>>& maze, vector<int>& entrance) {int m = maze.size(), n = maze[0].size();vector<vector<bool>> vis(m, vector<bool>(n, false));queue<pair<int, int>> que;que.emplace(entrance[0], entrance[1]);vis[entrance[0]][entrance[1]] = true;int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && !vis[nx][ny]) {vis[nx][ny] = true;if (maze[nx][ny] == '.') {if (nx == 0 || nx == m - 1 || ny == 0 || ny == n - 1) {return step;}que.emplace(nx, ny);}}}}}return -1;
}

困难

127. 单词接龙

字典 wordList 中从单词 beginWordendWord转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk

  • 每一对相邻的单词只差一个字母。
  • 对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
  • sk == endWord

给你两个单词 beginWordendWord 和一个字典 wordList ,返回 beginWordendWord最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0

示例 1:

输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:5
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。

示例 2:

输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:0
解释:endWord "cog" 不在字典中,所以无法进行转换。

提示:

  • 1 <= beginWord.length <= 10
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 5000
  • wordList[i].length == beginWord.length
  • beginWordendWordwordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

和这题类似433. 最小基因变化

int ladderLength(string beginWord, string endWord, vector<string>& wordList) {if (beginWord == endWord) {return 0;}unordered_set<string> vis;unordered_set<string> hash(wordList.begin(), wordList.end());if (!hash.count(endWord)) {return 0;}int step = 1;int n = beginWord.size();queue<string> que;que.push(beginWord);vis.insert(beginWord);while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {string str = que.front();que.pop();for (int i = 0; i < n; ++i) {string tmp = str;for (char ch = 'a'; ch <= 'z'; ++ch) {tmp[i] = ch;if  (hash.count(tmp) && !vis.count(tmp)) {if (tmp == endWord) {return step;}vis.insert(tmp);que.push(tmp);}}}}}return 0;
}

675. 为高尔夫比赛砍树

你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:

  • 0 表示障碍,无法触碰
  • 1 表示地面,可以行走
  • 比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度

每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。

你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。

你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1

可以保证的是,没有两棵树的高度是相同的,并且你至少需要砍倒一棵树。

示例 1:

img
输入:forest = [[1,2,3],[0,0,4],[7,6,5]]
输出:6
解释:沿着上面的路径,你可以用 6 步,按从最矮到最高的顺序砍掉这些树。

示例 2:

img
输入:forest = [[1,2,3],[0,0,0],[7,6,5]]
输出:-1
解释:由于中间一行被障碍阻塞,无法访问最下面一行中的树。

示例 3:

输入:forest = [[2,3,4],[0,0,5],[8,7,6]]
输出:6
解释:可以按与示例 1 相同的路径来砍掉所有的树。
(0,0) 位置的树,可以直接砍去,不用算步数。

提示:

  • m == forest.length
  • n == forest[i].length
  • 1 <= m, n <= 50
  • 0 <= forest[i][j] <= 109

每次要砍一棵树都是一次BFS求最短路。

const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};int cutOffTree(vector<vector<int>>& forest) {vector<pair<int, int>> trees;int m = forest.size(), n = forest[0].size();for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (forest[i][j] > 1) {trees.emplace_back(i, j);}}}auto cmp = [&](const pair<int, int>& a, const pair<int, int>& b) {return forest[a.first][a.second] < forest[b.first][b.second];};sort(trees.begin(), trees.end(), cmp);int ans = 0;int bx = 0, by = 0;for (auto [ex, ey] : trees) {int step = bfs(forest, bx, by, ex, ey);if (step == -1) {return -1;}ans += step;bx = ex, by = ey;}return ans;
}bool vis[55][55];
int bfs(vector<vector<int>>& forest, int bx, int by, int ex, int ey) { if (bx == ex && by == ey) {return 0;}int m = forest.size(), n = forest[0].size();memset(vis, 0, sizeof(vis));queue<pair<int, int>> que;que.emplace(bx, by);int step = 0;while (!que.empty()) {step++;int cnt = que.size();while (cnt--) {auto [x, y] = que.front();que.pop();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < m && ny >= 0 && ny < n && forest[nx][ny] != 0 && vis[nx][ny] == false) {if (nx == ex && ny == ey) {return step;}vis[nx][ny] = true;que.emplace(nx, ny);}}}}return -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[物联网iot]对比WIFI、MQTT、TCP、UDP通信协议

第一步&#xff1a;先理解最基础的关系&#xff08;类比快递&#xff09; 假设你要给朋友寄快递&#xff1a; Wi-Fi&#xff1a;相当于“公路和卡车”&#xff0c;负责把包裹从你家运到快递站。 TCP/UDP&#xff1a;相当于“快递公司的运输规则”。 TCP&#xff1a;顺丰快递&…

基于python的电影数据分析及可视化系统

一、项目背景 随着电影行业的快速发展&#xff0c;电影数据日益丰富&#xff0c;如何有效地分析和可视化这些数据成为行业内的一个重要课题。本系统旨在利用Python编程语言&#xff0c;结合数据分析与可视化技术&#xff0c;为电影行业从业者、研究者及爱好者提供一个便捷的电…

Java8 到 Java21 系列之 Lambda 表达式:函数式编程的开端(Java 8)

Java8 到 Java21 系列之 Lambda 表达式&#xff1a;函数式编程的开端&#xff08;Java 8&#xff09; 系列目录 Java8 到 Java21 系列之 Lambda 表达式&#xff1a;函数式编程的开端&#xff08;Java 8&#xff09;Java 8 到 Java 21 系列之 Stream API&#xff1a;数据处理的…

②EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

型号 协议转换通信网关 EtherCAT 转 Modbus TCP 配置说明 网线连接电脑到模块上的 WEB 网页设置网口&#xff0c;电脑所连网口的网段设置成 192.168.1.X&#xff08;X 是除 8 外的任一数值&#xff09;后&#xff0c;打开浏览器&#xff0c;地址栏输入 192.168.1.8 &#xff…

机器视觉--python基础语法

Python基础语法 1. Python标识符 在 Python 里&#xff0c;标识符由字母、数字、下划线组成。 在 Python 中&#xff0c;所有标识符可以包括英文、数字以及下划线(_)&#xff0c;但不能以数字开头。 Python 中的标识符是区分大小写的。 以下划线开头的标识符是有特殊意义的…

算法日常记录

1. 链表 1.1 删除链表的倒数第 N 个结点 问题描述&#xff1a;给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 思路&#xff1a;先让fast跑n步&#xff0c;然后…

14使用按钮实现helloworld(1)

目录 还可以通过按钮的方式来创建 hello world 涉及Qt 中的信号槽机制本质就是给按钮的点击操作,关联上一个处理函数当用户点击的时候 就会执行这个处理函数 connect&#xff08;谁发的信号&#xff0c; 信号类型&#xff0c; 谁来处理这个信息&#xff0c; 怎么处理的&…

【Golang】泛型与类型约束

文章目录 一、环境二、没有泛型的Go三、泛型的优点四、理解泛型&#xff08;一&#xff09;泛型函数&#xff08;Generic function&#xff09;1&#xff09;定义2&#xff09;调用 &#xff08;二&#xff09;类型约束&#xff08;Type constraint&#xff09;1&#xff09;接…

k8s常用总结

1. Kubernetes 架构概览 主节点&#xff08;Master&#xff09;&#xff1a; 负责集群管理&#xff0c;包括 API Server、Controller Manager、Scheduler 和 etcd 存储。 工作节点&#xff08;Node&#xff09;&#xff1a; 运行 Pod 和容器&#xff0c;包含 kubelet、kube-pr…

Android 单例模式全解析:从基础实现到最佳实践

单例模式&#xff08;Singleton Pattern&#xff09;是软件开发中常用的设计模式&#xff0c;其核心是确保一个类在全局范围内只有一个实例&#xff0c;并提供全局访问点。在 Android 开发中&#xff0c;单例模式常用于管理全局资源&#xff08;如网络管理器、数据库助手、配置…

ffmpeg滤镜使用

ffmpeg实现画中画效果 FFmpeg中&#xff0c;可以通过overlay将多个视频流、多个多媒体采集设备、多个视频文件合并到一个界面中&#xff0c;生成画中画的效果 FFmpeg 滤镜 overlay 基本参数 x和y x坐标和Y坐标 eof action 遇到 eof表示时的处理方式&#xff0c;默认为重复。…

OpenAI即将开源!DeepSeek“逼宫”下,AI争夺战将走向何方?

OpenAI 终于要 Open 了。 北京时间 4 月 1 日凌晨&#xff0c;OpenAI 正式宣布&#xff1a;将在未来几个月内开源一款具备推理能力的语言模型&#xff0c;并开放训练权重参数。这是自 2019 年 GPT-2 部分开源以来&#xff0c;OpenAI 首次向公众开放核心模型技术。 【图片来源于…

贪心算法,其优缺点是什么?

什么是贪心算法&#xff1f; 贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最优(局部最优)的选择&#xff0c;从而希望导致全局最优解的算法策略。 它不像动态规划那样考虑所有可能的子问题&#xff0c;而是做出局部最优选择&#xff0c;依赖这些选择来…

python string 类型字符拼接 +=的缺点,以及取代方法

在Python中&#xff0c;使用进行字符串拼接虽然语法简单&#xff0c;但在性能和代码维护方面存在明显缺陷。以下是详细分析及替代方案&#xff1a; 一、的缺点 性能低下 内存分配问题&#xff1a;字符串在Python中不可变&#xff0c;每次操作会创建新字符串对象&#xff0c;导…

web前端开发-JS

web前端开发-JS 什么是JavaScript Web标准也称网页标准,由一系列的标准组成,大部分由W3C(World Wide Web Consortium,万维网联盟)负责制定。三个组成部分: HTML:负责网页的结构(页面元素和内容)。CSS:负责网页的表现(页面元素的外观、位置等页面样式,如:颜色、大小等)。JavaS…

Turtle综合案例实战(绘制复杂图形、小游戏)

在学习了 Turtle 基本的绘图技巧后,我们可以通过结合多个概念和技巧,绘制复杂的图形或实现简单的小游戏。本章将介绍两个实战案例: 绘制复杂图形:结合前面所学的知识,绘制一个精美的多层次复杂图案。简单的游戏:利用 Turtle 实现一个简单的小游戏——蛇形游戏,这是一个经…

Python设计模式:克隆模式

1. 什么是克隆模式 克隆模式的核心思想是通过复制一个已有的对象&#xff08;原型&#xff09;来创建一个新的对象&#xff08;克隆&#xff09;。这种方式可以避免重复的初始化过程&#xff0c;从而提高效率。克隆模式通常涉及以下几个方面&#xff1a; 原型对象&#xff1a…

逻辑漏洞之越权访问总结

什么是越权访问漏洞&#xff1f; “越权访问漏洞” 是 “逻辑漏洞” 的一种&#xff0c;是由于网站系统的权限校验的逻辑不够严谨&#xff0c;没有对用户权限进行严格的身份鉴别&#xff0c;导致普通权限的用户做到了其它普通用户或管理员才能完成的操作&#xff0c;称之为“越…

超短波通信模拟设备:增强通信能力的关键工具

在全球信息化战争的背景下&#xff0c;通信系统扮演着至关重要的角色。为确保通信系统的稳定性和抗干扰能力&#xff0c;超短波通信模拟设备应运而生&#xff0c;为军事训练和通信干扰任务提供强大的支持。 设备特点及优势 便携性&#xff1a;设备体积小、重量轻&#xff0c;…

C++STL——容器-vector(含部分模拟实现,即地层实现原理)(含迭代器失效问题)

目录 容器——vector 1.构造 模拟实现 2.迭代器 模拟实现&#xff1a; ​编辑 3.容量 模拟实现&#xff1a; 4.元素的访问 模拟实现 5.元素的增删查改 迭代器失效问题&#xff1a; 思考问题 【注】&#xff1a;这里的模拟实现所写的参数以及返回值&#xff0c;都是…