1. 程式人生 > >【搜尋2】P1706 全排列問題

【搜尋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 }