这道题让我们用数学来解,应该很容易写出来
就像这样分叉,得到不同方案。
用代码实现就要讲到我们今天要学的DFS深度优先搜素。
思想
我们实现DFS算法其实并不需要真的创建一棵树(虽然很容易想到树)。
DFS思想:从根节点开始,沿着一条路径尽可能深地搜索,直到达到最深处,然后回溯到上一个可选择另一条路径的节点处,选择其他路径继续搜索,直至遍历完所有可能的路径。
图示
可以明白哈。
[AcWing]842. 排列数字(C++实现)dfs模板题,递归思想的解释
这篇文章作者将dfs的思想与递归思想的联系做了详细的解释,并呈现递归过程,非常推荐看一下。我属于是默认直接接受了使用递归的方式,没有深入思考二者的联系,,,
代码如下
#include<iostream>
using namespace std;
const int N=10;
int n;
int path[N];//用来存储可行的方案
bool st[N];//st用来标记用过的数字
void dfs(int u)
{
//u=n表示找到了一种方案
if(u==n){
for(int i=0;i<n;i++)
{
printf("%d ",path[i]);
}
puts(""); // 换行
return; // 这里相当于递归出口
}
//当没有走到最深处的时候
for(int i=1;i<=n;i++)//遍历我们有的数字
{
if(!st[i])//当该数字并没有被用过的时候
{
path[u]=i;//就可以将其加入路径中
st[i]=true;//同时更改标记
dfs(u+1);//加入一步之后,继续深搜,找更深层的下一步
st[i]=0;//当找完之后,逐层回溯,将用过的点重新置为0
//直到到达一个for循环,也就是i没有被选完的节点,即有多条路径的节点处,会继续执行if语句来得到其他的路径
}
}
}
int main()
{
scanf("%d",&n);
dfs(0);//从根节点开始深搜
return 0;
}
需要解释的部分都在注释里了。
递归过程图示
按代码执行一边递归过程可以帮助理解。画的有些乱emm,可以按照划圈①②这些标号看每一步,那些箭头从始端开始看,没到始端的时候不用管那些线条。 其实自己走一遍也不麻烦
代码感觉不好想,还是要多看看。
先写到这啦。
有问题欢迎指出!!一起加油!!