回溯法 n後問題

2021-09-27 22:05:58 字數 1574 閱讀 5195

題目:在乙個n*n的棋盤中,放置n個皇后,要求同一行、同一列、同一對角線上不能存在兩個皇后,求放置皇后的策略。

思路:將棋盤壓縮儲存為一維陣列ar[n],陣列中第i個元素就是棋盤第i行的皇后位置。這樣就不存在行衝突的問題,至於列衝突,判斷當前ar陣列中是否存在與將要放置皇后的j列下標相等的數,即可,若存在,則該位置不可放置皇后,j++;若不存在,則該位置可以防止皇后,對於對角線衝突,從棋盤左上角到右下角的主對角線及其平行線(即斜率為-1的各斜線),2個下標值的差值(行號-列號)相等;同理斜率為+1的斜線上,2個下標值的和(行號+列號)相等;因此若兩個皇后放置的位置分別是(i,j)和(k,l),且i-j=k-l或i+j=k+l,則說明這兩個皇后處於同一斜線上。以上兩個方程分別等價於i-k=j-l和i-k=l-j,由此可知只要|i-k|=|j-l|成立,就表明兩個皇后位於同一條斜線上。即它們所在的行列互減的絕對值相等,即| row – i | = | col – a[i] | 。這樣某個位置是否可以放置皇后的問題已經解決。

對於該問題,我們可以通過遞迴和非遞迴兩種方法實現,但遞迴效率不高,下面著重考慮非遞迴方法。

非遞迴方法的乙個重要問題是何時回溯及如何回溯的問題。程式首先對n行中的每一行進行探測,尋找該行中可以放置皇后的位置,具體方法是對該行的每一列進行探測,看是否可以放置皇后,如果可以,則在該列放置乙個皇后,然後繼續探測下一行的皇后位置。如果已經探測完所有的列都沒有找到可以放置皇后的列,此時就應該回溯,把上一行皇后的位置往後移一列,如果上一行皇后移動後也找不到位置,則繼續回溯直至某一行找到皇后的位置或回溯到第一行,如果第一行皇后也無法找到可以放置皇后的位置,則說明已經找到所有的解程式終止。如果該行已經是最後一行,則探測完該行後,如果找到放置皇后的位置,則說明找到乙個結果,列印出來。但是此時並不能再此處結束程式,因為我們要找的是所有n皇后問題所有的解,此時應該清除該行的皇后,從當前放置皇后列數的下一列繼續探測。

非遞迴完整**實現:

#include#include using namespace std;

bool place(int *ar,int k)//判斷是否可以放置皇后

else

}else

}return 0;

}

執行結果如圖:

遞迴**實現:

#include#include using namespace std;

bool place(int *ar,int k)//k為行下標

else

}cout執行結果如圖:

這篇部落格對於n後問題給出了三種方案,除了本文中提及的非遞迴的回溯法、遞迴的回溯法,還提到了一種位運算的方法。在文末,根據三種演算法對於同一大小規模的問題的執行時間,給出了針對於該問題三種演算法的效率排序:位運算》非遞迴的回溯法》遞迴的回溯法。

n後問題 回溯法

一.問題描述 在n n格仔上放置n個皇后,按照西洋棋規矩不可讓皇后相互攻擊,即如何兩個皇后不放在同一列同一行同一斜線上.二.演算法設計 將問題轉化為逐行放置皇后,即第一次放第1行,第二次放第2行,依次類推放至第n行皇后則放置完畢,如此每次放置只需考慮皇后的列衝突和斜線衝突.因為每次皇后都在新的一行放...

回溯法 n後問題

n後問題 1.問題描述 在n n格的棋盤上放置彼此不受攻擊的n個皇后。按照西洋棋的規則,皇后可以攻擊與之處在同一行或同一斜線上的棋子。n後問題等價於在n n格的棋盤上放置n個皇后,任何2個皇后不放在同一行或同一列或同一斜線上。2.演算法設計 用n元組x 1 n 表示n後問題的解。其中,x i 表示皇...

n後問題 回溯法

問題描述 在n n的棋盤上放置彼此不受攻擊的n個皇后。按西洋棋的規則,皇后可以與之處在同一行或者同一列或同一斜線上的棋子。n後問題等價於在n n格的棋盤上放置n皇后,任何2個皇后不放在同一行或同一列的斜線上。演算法設計 i k j l 成立,就說明2個皇后在同一條斜線上。可以設計乙個place函式,...