赞
踩
如果你还没有dfs的基础,可以先看我的上一篇文章:C语言递归+DFS(深度优先搜索算法)详解
第一排选择占(0,0),粉红线划的位置就不能选了。第二排此时可以占(1,2),(1,3)两个位置。我们先选择占(1,2)这个位置,此时我们发现第三排的位置都有标记不能选了,所以我们此时撞到了“南墙”,需要开始回溯。
回溯到状态①,我们选择第二排占(1,3)这个位置,欸此时我们发现第三排有位置可占了,我们占到(2,1)这个位置。但是很遗憾,我们用荧光笔标记后发现,第四排又没位置了,所以撞到了“南墙”开始回溯。此时就只能回溯到最初什么都没选的空白状态了。我们又开始占(0,1)这个位置,继续继续往下一排搜索......
这里提供一个成功的结果。
接着我们开始构思代码如何实现。
刚刚我们怎么模拟来着?我们一层一层往下搜的,那么这里可以用个for循环一层层的搜,这样我们就可以不用考虑“行”的冲突。
但是我们需要开一个某列是否已经有元素的状态数组,以及2个对角线状态数组(为什么是两个?你画个×)这样我们在判断一个位置是否可以占的时候,就检查这个位置的列状态数组,以及对角线状态数组。
我们惊奇的发现,其实对于某一对角线上的元素,他们都有规律的。一条是:行号+列号为定值,一条是行号+总行数-列号为定值。这样我们就可以为某一条对角线开一个状态数组啦。
哦对了,dfs还有位cp——恢复现场 记得写上它哦~ (你们三演燃冬吧)
- #include <iostream>
- using namespace std;
-
- const int N = 20;
- int n;
- char res[N][N];
- bool col[N], dg[N], udg[N];
-
- void dfs(int u)//u为行
- {
- if (u == n)
- {
- for (int i = 0; i < n; i++)
- {
- puts(res[i]);//puts输出自带换行
- }
- printf("\n");
- return;//回溯
- }
- for (int i = 0; i <n; i++)//i代表列
- {
- if (!col[i] && !dg[u + i] && !udg[u+n-i])
- {
- res[u][i] = 'Q';
- col[i] = dg[u + i] = udg[u+n-i] = true;
- dfs(u + 1);
- col[i] = dg[u + i] = udg[u+n-i] = false;//恢复现场
- res[u][i] = '.';
- }
- }
-
-
- }
- int main()
- {
- cin >> n;
- for (int i = 0; i < n; i++)//咱先把整个棋盘初始化一下
- {
- for (int j = 0; j < n; j++)
- {
- res[i][j] = '.';
- }
- }
- dfs(0);
-
- return 0;
- }
OK,本篇文章就结束啦,别慌,接下来还会发关于dfs的练习,咱主打一个熟能生巧。有什么不懂欢迎评论区提问,溜了溜了~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。