問題描述:要求在8x8的西洋棋棋盤上放入八個皇后,使得任意兩個皇后不能處於同一列,同一行,同一條斜線上。
演算法思路:
1) 判斷皇后之間有沒有衝突,要引入四個量–row(行號,也對應於皇后的編號),column[ ](列號),slash[ ](斜線方向), bslash[ ](反斜線方向);
2) 由棋盤的布局可以發現,在斜線方向上有15條對角線,每一條穿過的各個方格有如下性質:該方格的行號加列號等於乙個常量。15條對角線分別對應:0,1,2,…,14;而15條反斜線方向的對角線,每一條穿過的各個方格的行號與列號之差也是乙個常量,分別對應於:-7,-6,…,6,7。由這些特徵可以確定每一條對角線。程式中:slash[row + col] = 1 ,表示 第row行,第col列的方格所對應的斜線沒有衝突;bslash[row + col + 7] = 1 ,表示 第row行,第col列的方格所對應的反斜線沒有衝突(加7是因為陣列是要從0開始的)。然後陣列column[ ]表示列方向的情況, column[ i ] = 1,表示第 i 列無衝突,可放置皇后。所以,最終判斷判斷「column[h]&&slash[row+h]&&bslash[row-h+7]」是否為真;
3)然後從(0,0)開始放0號皇后,要令column[0] = 0,slash[0] = 0,bslash[7] = 0,表示這些方向都不能放皇后了。之後放1號皇后,例如放置在(1,j)上,它應與0號皇后不發生衝突,同樣要標出column[j] = 0,slash[1+j] = 0,bslash[1-j+7] = 0,依次類推,放後面的皇后。直到遇到某個皇后無法在任意乙個位置上擺放,那麼就要「回溯」–改變前乙個皇后的位置,再試自己能不能擺放,如果還不行,就再往回退,重新改變更前面的皇后的位置。
4)如果8個皇后都擺好了,就得到了一次成功的局。接著回退一步,試探第6號皇后還有沒有其他位置可放,如果有,再接著試探第7號皇后的擺放位置。這樣反覆試探,直到找出所有解。
程式執行後會顯示所以的擺放方法,一共有92種。
#include #define cosz 8
#define slsz 15
#define bssz 15
#define qusz 8
#define true 1
#define false 0
int column[cosz], slash[slsz], bslash[bssz];
int queen[qusz];
int row = 0, sum = 0;
void generate(void);
main()
for(s = 0; s <= 14; ++s)
printf("rownum:\t0\t1\t2\t3\t4\t5\t6\t7\n\n");
generate();
printf("total:%d\n",sum);
return 0;
}void generate(void)
else generate();
row--;
slash[row+h] = true;
bslash[row-h+7] = true;
column[h] = true;
} }}
C 用回溯遞迴解決「八皇后」問題
在很早以前,我曾經用c 寫過一篇使用回溯法來生成隨機數獨的部落格。這一次,考慮到這是一系列關於c 的部落格,所以利用c 的一些特點,來解決著名的 八皇后 問題。在迭代過程中,不停進行嘗試,如果不行則退回來,換一條路走,這就是 回溯法 的基本思想。在本例中,基本演算法如下 先遍歷棋盤的每一行,在每一行...
回溯法解決八皇后問題
在西洋棋棋盤上 8 8 放置八個皇后,使得任意兩個皇后之間不能在同一行,同一列,也不能位於同於對角線上。問共有多少種不同的方法,並且指出各種不同的放法。使用回溯法依次假設皇后的位置,當第乙個皇后確定後,尋找下一行的皇后位置,當滿足左上 右上和正上方向無皇后,即矩陣中對應位置都為0,則可以確定皇后位置...
用回溯法實現n皇后問題
首先說一下回溯法,如果在到達遞迴邊界前的某層,由於一些事實導致已經不需要任何乙個子問題遞迴,就可以直接返回上一層,這種方法叫做回溯法。include include const int maxn 50 int n,count 0,d maxn hashtable maxn void generate...