【搜索2】P1706 全排列问题
题目描述
输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字。
输入输出格式
输入格式:
n(1≤n≤9)
输出格式:
由1~n组成的所有不重复的数字序列,每行一个序列。每个数字保留5个常宽。
输入输出样例
输入样例#1: 复制
3
输出样例#1: 复制
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
解题思路:
1.构建一颗搜索树
以n=3为例:
n=3,就有3个数,1,2,3. 对1,画一颗搜索树如图:
红色字体表示已经数过了的数字。
其他情况同样如上,可以画出2,3的。这样对每一棵树进行深度搜索。可以找到全部结果。
2.程序实现:
2.1定义两个数组,一个b[100],存储最后的答案,一个a[100][2],用a[100][0]存储数字1-n,用a[100][1]存储该数字是否已经被搜索过了。
2.2伪代码实现:
void dfs(int k){
if(k==n){//已经从一个数字走到n个了
输出该次全排列;
retrun ;}
for(i=1->n){//n棵搜索树都应该走完
if(当前数字没有被走过){
将这颗树标记为走过;
存储到全排列数组b[k];
dfs(下一层);
恢复标记;}
}
}
代码:
1 #include<iostream> 2 using namespace std; 3 int b[100]; 4 int a[100][2]; 5 void dfs(int k,int n){ 6 if(k==n+1){ 7 8 for(int i=1;i<=n;i++){ 9 cout<<" "<<b[i]; 10 } 11 cout<<endl; 12 //cout<<" k: "<<k<<endl; 13 return; 14 } 15 for(int i=1;i<=n;i++){ 16 if(a[i][1]==0){ 17 // cout<<i<<" i "<<endl; 18 a[i][1]=1; 19 b[k]=i; 20 dfs(k+1,n); 21 a[i][1]=0; 22 23 } 24 } 25 26 27 28 } 29 int main(){ 30 int n; 31 cin>>n; 32 for(int i=1;i<=n;i++){ 33 a[i][0]=i; 34 a[i][1]=0; 35 } 36 dfs(1,n); 37 38 39 return 0; 40 }