前言:算法
對於接觸過編程的朋友來講,最開始瞭解的算法莫過於貪心或者遞歸;而提到遞歸,除了本博文前面介紹的漢諾塔問題之外,還有一個比較有趣的問題——八皇后問題。如今就跟你們理一理,分享一下代碼的實現思路。編程
八皇后問題指如何可以在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都沒法直接吃掉其餘的皇后?即任兩個皇后都不能處於同一條橫行、縱行或斜線上。數組
Step1 數據結構選擇數據結構
方案一:採用8*8二維數組存儲棋盤board(x,y);函數
方案二:採用8*1一維數組存儲棋盤每行放置的皇后位置q[i];優化
(爲方便代碼實現,這裏採用一維數組進行存儲)spa
Step2 遞歸跳出邊界code
因爲遞歸過程當中,每一種符合的方案都必須遍歷到最後一行,所以判斷邊界爲」i==8」blog
Step3 放置皇后的向下遞歸規則遞歸
根據定義,「任兩個皇后都不能處於同一條橫行、縱行或斜線上」即
(1)q[i]惟一
(2)q[i]!=q[x](x=1,2...,i-1)
(3)abs(q[i]-y)!=abs(i-x)
3.1列出知足八皇后問題的全部方案
1 #include <cstdio> 2 #include <cstring> 3 #include <math.h> 4 #define N 8 5 int q[N]; //queen position in 8 rows 6 //函數聲明 7 void pri(); 8 void dfs(int); 9 void placeon(int ,int ); 10 void takeout(int ,int ); 11 int canplace(int ,int ); 12 int main(){ 13 dfs(0); 14 return 0; 15 } 16 //函數定義 17 void pri(){ 18 for(int i=0;i<N;i++){ 19 for(int j=0;j<N;j++){ 20 if(q[i]==j) printf("A"); 21 else printf("_"); 22 } 23 printf("\n"); 24 } 25 printf("\n"); 26 } 27 void dfs(int x){ 28 if(x==N){pri();} 29 else{ 30 31 for(int i=0;i<N;i++)if(canplace(x,i)){ 32 placeon(x,i); 33 dfs(x+1); 34 takeout(x,i); 35 } 36 } 37 } 38 void placeon(int x,int y){q[x]=y;} 39 void takeout(int x,int y){q[x]=-1;} 40 int canplace(int x,int y){ 41 for(int i=0;i<x;i++) if(q[i]==y || fabs(x-i)==fabs(y-q[i])){ 42 return 0; 43 } 44 return 1; 45 }
3.2計算總方案數(僅添加一全局變量)
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #define N 8 5 int q[N]; //queen position in 8 rows 6 int cnt=0; //全局變量,方案總數 7 //函數聲明 8 void dfs(int); 9 void placeon(int ,int ); 10 void takeout(int ,int ); 11 int canplace(int ,int ); 12 int main(){ 13 dfs(0); 14 printf("Total:%d\n",cnt); 15 return 0; 16 } 17 //函數定義 18 void dfs(int x){ 19 if(x==N){cnt++;} 20 else{ 21 for(int i=0;i<N;i++)if(canplace(x,i)){ 22 placeon(x,i); 23 dfs(x+1); 24 takeout(x,i); 25 } 26 } 27 } 28 void placeon(int x,int y){q[x]=y;} 29 void takeout(int x,int y){q[x]=-1;} 30 int canplace(int x,int y){ 31 for(int i=0;i<x;i++) if(q[i]==y || fabs(x-i)==fabs(y-q[i])){ 32 return 0; 33 } 34 return 1; 35 }
3.3結果展現:
結語:
關於八皇后問題,基於回朔的思想(簡單講就是枚舉)利用遞歸的算法進行實現至關精巧。固然,本博文算法的實現其實應該還能夠剪枝優化,只不過本人在此只是拋磚引玉,但願感興趣的朋友後續本身進行嘗試!