搜索与回溯,是递归的一种重要形式,只要学好回溯,我们就能在一些类似于求方案数、走迷宫类的题目
我们只要学会了回溯,就好比站在了递归这个巨人的肩膀上
搜索与回溯学会了结构,就可以横跨“递归”大道
这是结构↓↓↓
样例题目 题目描述C++:
#includeusing namespace std; void dfs(int k){//层数 if(达到目的) 输出(或者方案数+1) else{ for(遍历所有的算符){ if(没有用到){ 标记 dfs(k+1)//下一层递归 回溯 } } } } Python:
def dfs(k): global ans#方案数 if(达到目的) :输出或ans+=1 else: for i in 所有的算符: if(没有用到): 标记 dfs(k+1)#递归下一层 回溯JavaScript:
function dfs(k){ if(达到目的)输出或ans+1 else{ for(遍历所有的算符){ if(没有用到){ 标记 dfs(k+1) 回溯 } } } }
在一个nXn的国际象棋棋盘上放置n(n<=12)个皇后,使它们不能互相攻击(即任意两个皇后不能在同一行、同一列或同一对角线上)。试求出所有方法。
输入输出格式 输入输入一个数n .(n<=12)
输出输出所有的排列方案总数。
输入输出样例 输入4
输出2
本题思路 注意事项:·1、需要用到深搜格式
·2、可以用一维数组(列表)来表示每个王后所放的位置,k层递归就是第k行
·3、判断是否放置合法:
1、斜着放合法:行列是否差值相等,如:|x1-x2|==|y1-y2|
2、列数放合法:遍历所有放过的Ai不相等
3、同行放合法:不可能不合法,因为递归层数就是行数
·4、如果层数(行数)> N 则方案数+1(调试时可以输出每次放的地方)并结束此次函数执行(return)
·5、记住了就可以写代码了
我们可以先简单的进行一个模板,简单的输入输出,最后解决dfs部分
C++
#include#include using namespace std; int n,ans,a[13]; void ba(int k){ if(k>n){ ans++; return; }else{ for(int j=1;j<=n;j++){ int bk=0; for(int i=1;i if((a[i]==j)||(abs(k-i)==abs(j-a[i]))){ bk=1; break; } } if(!bk){ a[k]=j; ba(k+1); a[k]=0; } } } } int main() { cin>>n; ba(1); cout< Python:
ans = 0 n = int(input()) a = [] def dfs(k): global ans,n,a if k == n: ans+=1 return for j in range(0,n):# 选列 flag=True for i in range(0,k): if a[i]==j or abs(i-k)==abs(a[i]-j): flag=False if flag: a.append(j) dfs(k+1) a.pop() dfs(0) print(ans)JS:
这个可以自己转,跟这两个语言的代码差不多,因为我有些不会
能不能点个赞再走



