大家好,这是第三次讲解dfs这是最后一次讲解例题了,这里dfs我给大家找几个例题把例题网站也给大家写上,大家昨晚我给大家下次放答案代码,然后讲解一些题目细节,我上次说了给大家整点这块内容的acm模板,大家自行理解,博主理解不了也讲不了,有大佬可以给解释下,不胜感激。
下次就讲BFS的内容了,上这次内容代码(讲解方式还是代数法理解)。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10;
int n;
int state[N]; // 0 表示还没放数,1~n表示放了哪个数
bool used[N]; // true表示用过,false表示还未用过
void dfs(int u)
{
if (u > n) // 边界
{
for (int i = 1; i <= n; i ++ ) printf("%d ", state[i]); // 打印方案
puts("");
return;
}
// 依次枚举每个分支,即当前位置可以填哪些数
for (int i = 1; i <= n; i ++ )
if (!used[i])
{
state[u] = i;
used[i] = true;
dfs(u + 1);
// 恢复现场
state[u] = 0;
used[i] = false;
}
}
int main()
{
scanf("%d", &n);
dfs(1);
return 0;
}
然后放一下代数法理解的过程
!!!!!!!!这不是代码这是代数法理解代码的过程,就是具体代码怎么执行操作的,还是老规矩能省篇幅则省,大家看的舒服一点,那个恢复现场的两行代码,第一行可以省不影响ac理解不了的友友们可以忽略,我也没写,但是第二行不能省,博主写下来了
dfs(1);
for(i=1;i<3;i++)//i=1去操作
st[1]=1;
use[1]=ture;//表示这个数用过了
dfs(2);
for(i=1) 由于use[1]=ture//后面的操作全部忽略直接i++
i++; i=2
st[2]=2;
use[2]=ture;
dfs(3);
for(i=1)由于use[1]、use[2]都被用过都等于了ture不满足!use[i]
i++; i=3
st[3]=3;
use[3]=ture;
dfs(4);
u>n printf(1,2,3);//st[1]——st[3]
然后回溯dfs(3)
use[3]=flase;//表示没选了
回溯dfs(2)
use[2]=flase;
i++; i=3
st[2]=3 use[3]=ture
dfs(3)for(i=1)use[1]=ture 所以i++ i=2 use[2]=flase !use[i]成立st[3]=2;
use[2]=ture;
dfs(4);
u>n printf(1,3,2);//st[1]-st[3]
use[3]=flase//回溯dfs(3)
use[2]=flase//回溯dfs(2)
回溯dfs(1)
//其实这里一遍循环就完了,剩下的完全可以找猫画虎做出了,但是我还是给大家写完吧,不过一些很简单的注释就不再重复了,大家读代码的时候也需要自己的理解才能进步
use[1]=flase
i++; i=2
st[1]=2;
use[2]=ture
dfs(2);
i=1 st[1]=1;use[1]=ture
dfs(3);
i=1 use[1]=ture i++ i=2 use[2]=ture i++ use[3]=flase
st[3]=3;use[3]=ture;
dfs(4);p(2,1,3);
use[3]=flase
回溯dfs(2);
use[1]flase
i++; i=3
st[2]=3 use[3]=ture;
dfs(3);
i=1 use[1]=flase;st[1]=1 use[1]=ture;
printf(2,3,1);
use[3]=flase;
use[1]=flase;
use[2]=flase;
回溯dfs(1);
i++ i=3
//剩下的大家当思考题吧,自己动手写一下剩下的过程理解一下,博主肝不动了555
讲一下acm模板总么写的,acm模板更强大这可以实现任意数全排列
//枚举排列的俩种常见方法:一是递归枚举,二是用STL中的next_permutation
//这个程序可以随机实现任意数的全排列
#include<iostream>
#include<algorithm>//包含next_permutation
using namespace std;
int main()
{
int n,p[10];
cin>>n;
for(int i=0;i<n;i++)scanf("%d",&p[i]);
sort(p,p+n);//排序得到p的最小排列
do{
for(int i=0;i<n;i++)printf("%d",p[i]);//输出排列p
puts(" ");
}while(next_permutation(p,p+n));//求下一个排列
return 0;
}
P1683 入门 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)P1025 [NOIP2001 提高组] 数的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)