DFS模板
void dfs(int depth)//depth表示当前的层数(或深度) { if(depth>n)//到达叶子节点,该路已走到尽头 return; for(int i=1;i<=n;i++)//n表示最大的值,即最大深度为n { if(b[i]==0)//b数组表示探索的状态,1表示已被探索,0表示尚未被探索 { b[i]=1;//标记当前的b[i]已被探索 a[level]=i;//记录当前的节点值 dfs(level+1);//进一步的搜索 b[i]=0;//还原当前的b[i]元素被探索的状态 } } }
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入一个整数n( 1<=n<=10)
输出所有全排列
每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格)
3
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include<bits/stdc++.h> #include<queue> using namespace std; const int N=100; typedef long long ll; int n,a[10010],b[10010]; void print() { for(int i=1;i<=n;i++) { printf("%5d",a[i]); } cout<<endl; } void dfs(int level) { if(level==n+1) { print(); return; } for(int i=1;i<=n;i++) { if(b[i]==0) { b[i]=1; a[level]=i; dfs(level+1); b[i]=0; } } } int main() { cin>>n; dfs(1); }
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,y[100010],s,ans[100010]; bool check(int x)//剪枝,判断两点的位置\\ 两点的斜率的绝对值不得等于1;两点不得在同一水平线上(包括同一行和同一列) { for(int i=1;i<x;i++)//i本身就是指行号,y[i]表示对应的列号 { if(abs(x-i)==abs(y[x]-y[i])||y[x]==y[i]||x==i) { return 0; } } return 1; } void dfs(int num) { if(num>n)//越界处理 { s++; return; } for(int i=1;i<=n;i++) { y[num]=i;//将当前的行号赋值给第num个皇后 if(check(num)) dfs(num+1);//进行下一步的搜索 } } int main() { for(int i=1;i<=10;i++) { n=i; s=0; dfs(1); ans[i]=s; } while(~scanf("%d",&n)&&n) printf("%d\n",ans[n]); }
原文:https://www.cnblogs.com/jackwang-sparrow/p/13384779.html