經典的n皇后問題描述為:在乙個n x n的棋盤上放置n個皇后,要求任意的兩個皇后都不在同一行、同一列或同一條對角線上,問在給定n的情況下有多少種放置的方法。
求解n皇后最典型的方法是回溯法,此方法的思路可以概括為:在第一行佔據乙個位置,接著在下一行佔據乙個位置,判斷兩個位置之間是否存在衝突。如果不存在衝突,則繼續在下下行佔據乙個位置,判斷與前面的兩個位置之間是否存在衝突,如果不存在衝突則繼續往下佔據位置,當佔據到最後一行,且佔據的位置與前n - 1行的位置均不衝突,那麼便成功找到了一種放置皇后的方案。
如果在當前行佔據的位置與前面的位置存在衝突,那麼需要尋找當前行的其他位置,直到找到不衝突的位置並進入下一行尋找,或者當前行尋找完畢未發現不衝突的位置,那麼則返回上上行,尋找上上行的其他位置,如果在上上行也沒有找到,則繼續向上尋找直到整個棋盤遍歷完畢。
由n皇后問題可知,在棋盤的每一行和每一列都只能放置乙個皇后,那麼我們在儲存資料時便無需定義n x n的二維陣列,直接定義長度為n的一維陣列即可,即陣列的索引可以表示行的值,而索引對應的值則表示列的值。
判斷兩個皇后之間是否存在位置衝突的簡單方法為:判斷橫座標是否相等,判斷縱座標是否相等,以及判斷兩者橫座標之差的絕對值是否等於縱座標之差的絕對值。
可以這麼理解,兩者橫縱座標自然不能相等,而如果兩者橫座標之差的絕對值等於縱座標之差的絕對值,那麼可以判定兩者在乙個正方形的斜對角上,即不滿足不在對角線上這一條件。
舉例來說即是,假設皇后a的座標為 (xa, ya),皇后b的座標為 (xb, yb),那麼判斷兩者是否存在位置衝突的c/c++**如下:
bool conflict= false;
if (xa == xb || ya == yb || abs(xb - xa) == abs(yb - ya))
依照上述回溯法的思路,假設n = 8,則對應的c/c++**如下:
#include inline int abs(int x)
return x;
}bool isconflict(int xa, int ya, int xb, int yb)
return result;
}void search(int rowindex, int ncols, int* pos, int& cnt)
} if (!conflict)
else
} }}int main(int argc, char* ar**)
用回溯法實現n皇后問題
首先說一下回溯法,如果在到達遞迴邊界前的某層,由於一些事實導致已經不需要任何乙個子問題遞迴,就可以直接返回上一層,這種方法叫做回溯法。include include const int maxn 50 int n,count 0,d maxn hashtable maxn void generate...
回溯法求解N皇后問題。
n皇后問題就是 不存在兩個皇后同行或同列,或在同一斜線上。如下圖所示。黑色塊表示其中乙個皇后放在了第二行,第三列。這時,只有綠色圈圈才能放其他的皇后。回溯法的基本思想 確定了解空間的組織結構後,回溯法就從開始結點 根結點 出發,以深度優先的方式搜尋整個解空間。這個開始結點就成為乙個活結點,同時也成為...
回溯法求解n皇后問題
皇后問題 由n n個方塊排成n行n列的正方形稱為 n元棋盤 如果兩個皇后位於棋盤上的同一行或同一列或同一對角線上,則稱她們為互相攻擊,現要求找使n元棋盤上的n個皇后互不攻擊的所有布局。假設棋盤上每一行放置乙個皇后,分別用自然數0,1,2,n 1。首先定義乙個長度為n的一維陣列q,其中每乙個元素去q ...