蓝桥杯算法练习笔记(7)__深度优先搜索 DFS
定义方向数组 主函数 定义马的八个可能移动方向。 主函数 如果找到目标位置,输出步数,否则输出 定义方向数组 主函数 初始化方向数组 主函数 定义马的八个可能移动方向。 主函数
发布日期:2021-04-30 21:01:55
浏览次数:134
分类:精选文章
本文共 5184 字,大约阅读时间需要 17 分钟。
深度优先搜索(DFS)应用实例
1. 迷宫问题
迷宫问题是一个经典的图遍历问题,通常使用深度优先搜索(DFS)来解决。DFS通过尽可能深入搜索一条路径,然后回溯,找到从起点到终点的路径。
实现代码
#include#include using namespace std;int n, m;string maze[110];bool vis[110][110];bool in(int x, int y) { return (0 <= x && x < n && 0 <= y && y < m);}bool dfs(int x, int y) { if (maze[x][y] == 'T') { return true; } vis[x][y] = true; for (int i = 0; i < 4; ++i) { int tx = x + dir[i][0]; int ty = y + dir[i][1]; if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) { if (dfs(tx, ty)) { return false; } } } vis[x][y] = false; maze[x][y] = '.'; return false;}int main() { cin >> n >> m; for (int i = 0; i < n; ++i) { cin >> maze[i]; } int x, y; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (maze[i][j] == 'S') { x = i; y = j; break; } } if (x != -1) { break; } } dfs(x, y); return 0;}
解题思路
dir,表示四个可能的移动方向。in(x, y) 函数检查坐标是否在迷宫范围内。dfs(x, y) 函数实现深度优先搜索: - 如果当前位置是目标位置
T,返回true。 - 标记当前位置为已访问,尝试四个方向移动。
- 递归搜索目标位置,如果找到路径返回
true,否则返回false。
main 读取输入,初始化迷宫,找到起始位置并调用 dfs。2. 象棋走马问题
在象棋中,马的走法具有跳跃特性,通常可以用DFS解决其路径问题。
实现代码
#includeusing namespace std;char s[10][10];int dir[8][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}};bool f = false;bool vis[10][10];int ans = 1000000;bool in(int x, int y) { return (0 <= x && x < 10 && 0 <= y && y < 9);}void dfs(int x, int y, int step) { vis[x][y] = true; if (s[x][y] == 'T') { f = true; if (step < ans) { ans = step; } return; } if (step >= 3) { return; } for (int i = 0; i < 8; ++i) { int tx = x + dir[i][0]; int ty = y + dir[i][1]; if (in(tx, ty) && s[tx][ty] != '#' && !vis[tx][ty]) { dfs(tx, ty, step + 1); } }}int main() { int x, y; for (int i = 0; i < 10; ++i) { for (int j = 0; j < 9; ++j) { if (s[i][j] == 'S') { x = i; y = j; break; } } if (x != -1) { break; } } dfs(x, y, 0); if (f) { cout << "Yes " << ans << endl; } else { cout << "No" << endl; }}
解题思路
in(x, y) 检查坐标是否在棋盘范围内。dfs(x, y, step) 实现DFS,参数 step 记录当前步数。main 读取输入,初始化棋盘,找到起始位置并调用 dfs。No。3. 草地块问题
草地块问题可以通过DFS统计相连区域数量。
实现代码
#includeusing namespace std;char mp[105][105];bool vis[105][105];int n, m;void dfs(int x, int y) { if (x < 0 || x >= n || y < 0 || y >= m || vis[x][y] || mp[x][y] == '.') { return; } vis[x][y] = true; dfs(x - 1, y); dfs(x + 1, y); dfs(x, y - 1); dfs(x, y + 1);}int main() { cin >> n >> m; int cnt = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> mp[i][j]; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (!vis[i][j] && mp[i][j] == '#') { dfs(i, j); cnt++; } } } cout << cnt << endl;}
解题思路
dir。dfs(x, y) 函数递归遍历相连区域。main 读取输入,初始化棋盘,统计草地块数量。4. 树的子节点问题
树的子节点问题可以通过DFS计算每个节点的后代数量。
实现代码
#include#include using namespace std;vector > son;bool f[100005];int ans[100005];void dfs(int u) { int ret = 1; for (int i = 0; i < son[u].size(); ++i) { ret += dfs(son[u][i]); } ans[u] = ret; return ret;}int main() { int n, x, y; cin >> n; son.resize(n + 1); for (int i = 0; i < n - 1; ++i) { cin >> x >> y; son[x].push_back(y); f[y] = true; } for (int i = 1; i <= n; ++i) { if (!f[i]) { int u = i; break; } } dfs(u); for (int i = 1; i <= n; ++i) { cout << ans[i] << endl; }}
解题思路
dir。dfs(u) 计算节点 u 的后代数量。main 读取输入,构建树结构,调用 dfs 并输出结果。5. 马可以走到哪里
马的走法问题可以通过DFS计算三步内可达的位置。
实现代码
#includeusing namespace std;int n, m;char mp[105][105];bool vis[105][105];int a[8][2] = {{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {-2, 1}, {2, -1}, {-2, -1}};void dfs(int x, int y, int step) { if (x < 0 || x >= n || y < 0 || y >= m) { return; } if (step > 3) { return; } for (int i = 0; i < 8; ++i) { int tx = x + a[i][0]; int ty = y + a[i][1]; if (tx < 0 || tx >= n || ty < 0 || ty >= m) { continue; } if (step < 3 && mp[tx][ty] == 'B') { dfs(tx, ty, step + 1); } }}int main() { cin >> n >> m; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { mp[i][j] = '.'; } } int x, y; cin >> x >> y; mp[x][y] = 'B'; dfs(x, y, 0); // 输出可达的位置 for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (vis[i][j]) { cout << '#'; } else { cout << '.'; } } }}
解题思路
dfs(x, y, step) 实现DFS,跳过超过三步的情况。main 读取输入,初始化棋盘,调用 dfs 并输出结果。发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2026年05月29日 14时58分08秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
php实现短信验证功能
2023-03-01
php实现逆转数组
2023-03-01
PHP实现通过geoip获取IP地理信息
2023-03-01
PHP实现页面静态化、纯静态化及伪静态化
2023-03-01
php容许ajax跨域,PHP设置允许ajax跨域请求的两种常见方法
2023-03-01
RabbitMQ进程结构分析与性能调优
2023-03-01
PHP对接百度地图
2023-03-01
PHP对表单提交特殊字符的过滤和处理
2023-03-01
php对象引用和析构函数的关系
2023-03-01
RabbitMQ HTTP 认证后端项目常见问题解决方案
2023-03-01
PHP将图片转换成base64格式(优缺点)
2023-03-01
php将多个值的数组去除重复元素
2023-03-01
php局域网上传文件_PHP如何通过CURL上传文件
2023-03-01
PHP工具插件大全
2023-03-01
php布尔值的++
2023-03-01
PHP常量、变量作用域详解(一)
2023-03-01
PHP应用目录结构设计
2023-03-01
PHP应用程序连接MSQL数据库Demo(附crud程序)
2023-03-01
PHP应用程序连接Oracle数据库Demo(附Oracle客户端安装文件)
2023-03-01