遞歸之八皇后

前言:算法

  對於接觸過編程的朋友來講,最開始瞭解的算法莫過於貪心或者遞歸;而提到遞歸,除了本博文前面介紹的漢諾塔問題之外,還有一個比較有趣的問題——八皇后問題。如今就跟你們理一理,分享一下代碼的實現思路。編程

1. 問題介紹:

八皇后問題指如何可以在 8×的國際象棋棋盤上放置八個皇后,使得任何一個皇后都沒法直接吃掉其餘的皇后?即任兩個皇后都不能處於同一條橫行、縱行或斜線上。數組

 

2. 問題分析:

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. 代碼實現

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結果展現:

 


 

結語:

關於八皇后問題,基於回朔的思想(簡單講就是枚舉)利用遞歸的算法進行實現至關精巧。固然,本博文算法的實現其實應該還能夠剪枝優化,只不過本人在此只是拋磚引玉,但願感興趣的朋友後續本身進行嘗試!

相關文章
相關標籤/搜索