八皇后問題,是乙個古老而著名的問題,是回溯演算法的典型例題。該問題是十九世紀著名的數學家高斯2023年提出:在8x8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。
uc科技筆試最後一道題也考了這個,用遞迴演算法最多得2/3的分數,非遞迴演算法可得滿分。
這裡用到的是回溯演算法,如迷宮問題也一般用回溯實現。
用陣列模擬棧,實現回溯操作。陣列大小可以事先算出,棧深度,最大不超過行數。
把全域性的問題分解為8步,每一行算一步,每步需要儲存8列位置的資訊(gmask),"/"型斜線上的位置資訊(xflag),"\"型斜線上的位置資訊(eflag),當前的行號(lay),以及計算過的列資訊(cflag,避免回溯時重複計算)。
橫向設為i(i=0,1,2..),縱向設為j(0,1,2...),那麼"/"型斜線上的皇后座標應該滿足j-i=c,c~[-6,6],通過+6操作對應到0-12,可用13bit位
儲存(eflag)、"\"型斜線上的皇后座標應該滿足j+i=c,c~[1,13],通過-1操作對應到0-12,可用13bit位
儲存( xflag)。
當某一步計算時gmask的低八位填滿時說明找到一種解,棧頂元素出棧,繼續下一步;找不到可放的位置時,棧頂元素出棧,即回溯到上一步;否則,更新棧頂元素的cflag,避免重複計算,並將新找到的位置資訊,入棧。
**如下:
#ifndef __debug
#define __debug
#endif
#include
using namespace std;
typedef unsigned char byte;
struct node
;int main(int argc,char** argv)
int j;
for(j=0;j<8;j++)
if(j==8)}}
cout<#ifdef __debug
cout<<"press any key to continue..."}執行結果92.
八皇后問題遞迴和非遞迴演算法
大名鼎鼎的八皇后問題。相信大家都耳熟能詳。八皇后的是乙個典型的用回溯法求解的問題。在回溯法中的乙個關鍵是要動態儲存求解空間對應的程式所處的狀態,特別是能夠進行狀態 回滾 當一發現個部分解再往下去不能成為合法的解時,要回溯到這個部分解之前所處的狀態。程式狀態的 前進 和 回滾 用ban和unban函式...
八皇后問題(非遞迴版)
include iostream include stack using namespace std const intmaxsize 8 棋盤大小 intchess maxsize maxsize 棋盤 定義棧結點,表示乙個皇后的位置 struct node 進行皇后問題處理 返回找到的答案個數 ...
回溯法 八皇后問題的遞迴與非遞迴演算法
八皇后的問題非常有名,初次理解可能稍有難度,不過多看書,看部落格和 幾遍下來,也基本清晰。首先不用想初始的情況,先假設前面已經排列好了幾個皇后,即將排列下乙個皇后。依次遍歷八個位置,然後與之前的進行判斷這個位置是否可行,如可行則進行下乙個皇后,否則則移動位置繼續判斷。很簡單。但是有兩個個問題 1 不...