寒假 全排列與n皇后

2021-09-11 05:40:36 字數 1350 閱讀 6478

遞迴很久之前就學過了,主要包括兩個重要點:1.遞迴邊界 2.遞迴式   例如斐波那契數列、漢諾塔等就可以很好處理。

這次要記錄的是全排列和八皇后問題。

全排列就是給定幾個正數,按順序排列不重複。例如 (123)(132)(213)(231)(312)(321)這就是1、2、3三個數的全排列。如何利用遞迴來實現呢?記當前為第index位,如果給定的是n個數的全排列 ,則開設乙個n的陣列table記錄被使用情況,從小到大遍歷這個table查詢第乙個未被使用的數字,如果當前數字未被使用,則把它放在第index位,並且記為被使用過,然後遞迴呼叫下一位,遞迴邊界是當index==n時。

void generates(int t)

printf("\n");

return ;

}for(int i=1;i<=n;i++)//列舉 1~n 如果此位沒有用 則把他寫在此位並把標誌設為true 然後繼續下一位。

}}

以上**即遞迴**。

下面討論n皇后問題

n皇后是指在n*n的西洋棋棋盤上放n個皇后,使得n個皇后兩兩不在同一行、同一列、同一對角線上,求合法的方案數。

n皇后問題可以和全排列很好的結合起來。試想全排列排第index位即在棋盤的第index列上尋找放置皇后的位置。則這樣能夠保證了所有的皇后一定不在同一行和同一列上,那麼接下來就只需要判斷是否在同乙個對角線上即可。判斷的方法當然是橫座標之差與縱座標之差相同。在下面有兩種方法:1.暴力法 2.回溯法

1.暴力法

在產生乙個全排列之後,再進行測試,對每兩個皇后都進行監測,是否在同乙個對角線上,如果是則不記錄,否則方案數+1。

void generates(int t)}}

if(flag)

count++;

return;

}for(int i=1;i<=n;i++)//列舉 1~n 如果此位沒有用 則把他寫在此位並把標誌設為true 然後繼續下一位。

}}

2.回溯法

回溯法的思想是在當前放置乙個皇后之後就監測是否與之前放置的皇后衝突,如果衝突直接進行返回上層繼續遞迴,否則繼續進行放置。

void generatep(int index)

for(int x=1;x<=n;x++)

{if(hashtable[x]==false)//當前要往第index列第x行插入

{bool flag=true;

//遍歷之前的列上的皇后 看看與當前這個是否在對角線上

for(int pre=1;pre結束。

遞迴 全排列與n皇后

輸出全排列利用遞迴實現 每一層遞迴排列好乙個數字,抵達邊界就輸出 include using namespace std int n,p 11 hashtable 11 void generatep int index for int x 1 x n x int main n皇后問題可以理解為全排列...

遞迴 全排列 N皇后

遞迴求出全排列,如輸出1到5的全排列 include const int maxn 11 int n,p maxn p存放已經排進來的數,n即為要求輸出1 n的全排列 bool hashtable maxn void generatep int index printf n return for i...

全排列問題與n皇后問題

全排列問題 基本思想 從遞迴的角度考慮,將 輸出從1 n的全排列 分為若干個子問題 輸出以1為開頭的全排列 輸出以2為開頭的全排列 於是不妨設定乙個陣列p,用來存放當前排列 再設定乙個雜湊陣列hashtable,其中hashtable x 當整數x已經在陣列p中時為true。遞迴邊界 當index達...