DFS基础-----刷题合集--1(全排列,八皇后,迷宫),让你明白DFS的基础用法
二刷dfs相关题目
洛谷P1706 全排列
https://www.luogu.com.cn/problem/P1706
一个全排列问题,这次没有选择深搜,直接用next_permutation这个函数即可(以后碰到排列问题会这个函数真的很爽,不过查阅后有个缺点就比较慢)
直接贴代码,可以学习下next_permutation函数的用法
头文件 <algorithm>
next_permutation:
返回类型是bool类型,这导致了经常与do while连用
函数名(数组排序开始的位置,数组排序最后一个元素的下一个位置)
使用这个函数可以得到一个序列的下一个升序序列
比如 1 2 3,下一个序列就是1 3 2
模拟实现这个函数有一定难度,实现办法是双指针(这个对双指针要求较高,有兴趣的同学可以尝试了解一下)
#include<iostream>
#include<algorithm>
using namespace std;int main()
{int n;int a[20];cin >> n;for (int i = 1; i <= n; i++){a[i] = i;}do{for (int i = 1; i <= n; i++){printf("%5d", a[i]);}printf("\n");} while (next_permutation(a + 1, a + 1 + n));return 0;
}
另外一种解法是dfs 选数字
1 1 1
2 2 2
3 3 3
三组数字 按列选 从左往右选1 2 3就是一次完整的dfs,下面直接贴代码
#include<bits/stdc++.h>
using namespace std;
int n;
int vis[20];
int a[20];
void pr()
{for (int i = 1; i <= n; i++){printf("%5d", a[i]);}printf("\n");
}
void dfs(int x)
{if (x > n){pr();//递归出口,也可以写成x==n+1return;}for (int i = 1; i <= n; i++)//从1到n选数字{if (!vis[i])//如果这个数字没被访问过可选{vis[i] = 1;//选他a[x] = i;//记录下这个数字,不然你咋打印dfs(x + 1);//选下一个数字vis[i] = 0;//回溯 选完一组完整的数字后“归零” 这一步只有在x==n+1返回的时候才会执行}}
}
int main()
{cin >> n;dfs(1);//开始深搜return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
洛谷P1219
https://www.luogu.com.cn/problem/P1219
典型的八皇后问题
这题乍一看和第一题有关系??
还真有,你把落子想象成一个选数字的过程
比如:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
在这里每个数字代表一个位置,你去选他是不是和第一题就联系起来了
这里还有一种思想:把一群有着相同特质的东西看做一个东西,这里就是把坐标特点相同的点看成了一个数字,所以可以设置一个数组当作条件判断是否可以落子
解题关键:
坐标特点:对角线上的点 横纵坐标之和或者横纵坐标之差相等
直接上代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int n;
int col[40] = { 0 };
int a[40] = { 0 };//左上到右下
int b[40] = { 0 };//右上到左下
int ans[40];//记录下打印的位置
int cnt = 0;
void pr()
{for (int i = 1; i <= n; i++){printf("%d ", ans[i]);}printf("\n");
}
void dfs(int x)
{if (x > n){cnt++;//计数器,记录解的个数if (cnt <= 3)//题目只要前三组解{pr();}return;}for (int i = 1; i <= n; i++){if (!col[i] && !a[i - x + n] && !b[i + x])//不在同一列&&不在一条对角线&&不在另一条对角线//为什么我没写不在同一行?因为递归本身就是一行一行进行的啊{//访问的置为1col[i] = 1;a[i - x + n] = 1;b[i + x] = 1;ans[x] = i;//记录下这个数字,不然没法打印dfs(x + 1);//下一层递归//回溯 一次完整的dfs后置为0col[i] = 0;a[i - x + n] = 0;b[i + x] = 0;}}
}
int main()
{cin >> n;dfs(1);//开始深搜cout << cnt << endl;//打印方案的总数return 0;
}
emmmm,可能看我写的很长,实际上代码逻辑很简单.
第一次碰到难理解正常,慢慢品.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
洛谷P1605 迷宫
https://www.luogu.com.cn/problem/P1605
典型的迷宫问题
直接上代码:
逻辑和上面也差不多,都是落子的问题
关键点是用数组来表示落子的四个方向(上下左右)
数组里的数字是x,y坐标的变化
#include<iostream>using namespace std;
int n, m, t;
int sx, sy, fx, fy;
int tx, ty;
int board[10][10];//标记障碍物
int vis[10][10];//是否访问过
int dx[] = { -1, 1, 0, 0 };//四个方向,对应上下左右
int dy[] = { 0, 0, -1, 1 };//四个方向,对应上下左右
int cnt;//计数器
void dfs(int x, int y)
{if (x== fx&&y == fy)//递归出口 到了终点跳出就行{cnt++;return;}for (int i = 0; i < 4; i++){int nx = x + dx[i];//落子的x坐标 nx(newx)新的xint ny = y + dy[i];//落子的y坐标if (nx > 0 && nx <= n&&ny > 0 && ny <= m&&!vis[nx][ny] && !board[nx][ny]){vis[nx][ny] = 1; board[nx][ny] = 1;//这行可以省略,因为和上一行一个意思dfs(nx, ny);vis[nx][ny] = 0;board[nx][ny] = 0;//这行可以省略}}
}int main()
{cin >> n >> m >> t;cin >> sx >> sy >> fx >> fy;for (int i = 1; i <= t; i++){cin >> tx >> ty;board[tx][ty] = 1;//障碍物置为1}vis[sx][sy] = 1;//这一句话相当重要 在迷宫问题中十分容易遗漏dfs(sx, sy);cout << cnt << endl;return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dfs基础入门的逻辑都差不多
dfs+递归出口+循环控制+回溯(一次完整的递归(dfs)后回到上一步).
谢谢阅读.
DFS基础-----刷题合集--1(全排列,八皇后,迷宫),让你明白DFS的基础用法相关推荐
- HDLBits刷题合集—9 Arithmetic Circuits
HDLBits刷题合集-9 Arithmetic Circuits HDLBits-66 Hadd Problem Statement 创建一个半加器.半加器将两个输入(不带低位的进位)相加产生和和向 ...
- CCF刷题合集(部分题解)
CCF 刷题满分代码 注意第一题的话如果比较简单有的我可能没写,有链接的可能写了也只有代码. 202012 202012-1 期末预测之安全指数 CCF 202012-1 期末预测之安全指数 2020 ...
- 2022.7.26刷题合集
目录 1.矩阵快速幂 2.KMP字符串匹配 3.口袋的天空 4.Barn Echoes G 5.租用游艇 6.shortest path of the king 1.矩阵快速幂 #include< ...
- python基础教程教材-Python3零基础教材电子书合集
Python3零基础教材电子书合集,传送门:https://www.52pojie.cn/thread-676318-1-1.html 一.<Python编程从入门到实践> 链接:http ...
- 2020年前端面试之JS手写代码题合集
2020年前端面试之JS手写代码题合集 预计会有上千道题,后续慢慢补! 1. 写一个把字符串大小写切换的方法 function caseConvert(str){return str.replace ...
- python零基础自学教材-Python3零基础教材电子书合集
Python3零基础教材电子书合集,传送门:https://www.52pojie.cn/thread-676318-1-1.html 一.<Python编程从入门到实践> 链接:http ...
- python入门电子版-Python3零基础教材电子书合集
Python3零基础教材电子书合集,传送门:https://www.52pojie.cn/thread-676318-1-1.html 一.<Python编程从入门到实践> 链接:http ...
- 计算机组成原理常考大题合集
计算机组成原理常考大题合集 1.在"Cache-主存-辅存"三级存储体系中,"Cache-主存"结构与"主存-辅存"结构的引入为了解决什么问 ...
- 零基础学python全彩版电子书-Python3零基础教材电子书合集
Python3零基础教材电子书合集,传送门:https://www.52pojie.cn/thread-676318-1-1.html 一.<Python编程从入门到实践> 链接:http ...
最新文章
- 写出下列数学式对应的python表达式_Python程序设计课后习题答案-第一单元
- python mysql 转义方法
- 将远程桌面客户端配置为连接到特定端口
- 开关电源过流保护-打嗝模式
- 阿里DataV案例:制作实时销售大屏流程
- OD 调试带启动参数的程序
- Spring源码学习:day2
- 用bit字段来判断性别等
- Classification分类halcon算子,持续更新
- 【51NOD】1201 整数划分
- Error running ‘transmission‘: Unable to open debugger port (127.0.0.1:52469): java.net.SocketExcepti
- python科学数据分析_python数据分析-科学计数法
- 金蝶KIS商贸版开发销售出库单、销售订单带商品图片打印单据
- 想要学习云计算,不知道如何开始?我来说下云计算的学习流程,分享一些学习资源。
- 「 运动控制 」“ADRC自抗扰控制技术”(Active Disturbance Rejection Control)研究
- 不要眼馋咪蒙一年赚几千万!今天做自媒体依然还来得及!
- Excel如何用IF函数进行数据筛选
- Fluent Search
- 中国小微企业调查数据CMES:小型微型家庭作坊式企业收支工商税收营商情况
- Python中的文件路径