一維陣列解決n皇后問題(暴力法)
阿新 • • 發佈:2018-12-14
以5皇后為例遞迴實現:考慮每行只放置一個皇后、每列也只能放置一個皇后,那麼如果把n列皇后所在的行號依次寫出,那麼就會是1-n的一個排列。上圖a中的排列為24135,對於b來說就是35142。於是就只需要列舉1-n的所有排列,檢視每個排列對應的放置方案是否合法,統計合法的方案。
由於當到達遞迴邊界時生成了一個排列,所以需要再其內部判斷方案是否合法,即遍歷每兩個皇后,判斷他們是否在同一對角線上。
#include<cstdio> #include<stdlib.h> const int maxn=10; int n,P[maxn],hashTable[maxn]={false}; //P[]陣列是用來儲存皇后的位置排列,例如24135,hashTable[x]為true時表示x這個數在P[]中 int count=0; void generateP(int index) { if(index==n+1) { //需要判斷達到邊界條件的排列是否滿足n皇后條件 bool flag=true;//flag為true表示當前的排列為一個合法的方案 for(int i=1;i<=n;i++)//遍歷任意兩個皇后 { for(int j =i+1;j<=n;j++) {/*,以n=5為例:針對這裡為什麼是j=i+1,這是因為當i=1時j有2 3 4 5,當i=2時有3 4 5,其中的1 與當i=1時 有1 2 和2 1 這兩種求絕對值是一樣的,但是不能出現相同的例如 2,2 這就相當於p[2]等於某個x p[2]也等於某個相同的x 這是不允許的,因為這樣做後就相當於p[index]只有4個了而不是5個了結果就會出錯,所以要選擇跳過2 2 這一項,就從j=i+1開始迭代 。對於一個已經在內部排列好的一個排列P它也不可能出現兩個相同的座標如,P[2] P[2],應該是兩個不同的座標。例如一個合法的方案: P[2]=1 P[4]=2 P[1]=3 P[3]=4 P[5]=5; */ if(abs(i-j)==abs(P[i]-P[j])) { flag=false; } } } if(flag) count++; return; } for(int x=1;x<=n;x++) { if(hashTable[x]==false) { P[index]=x; hashTable[x]=true; generateP(index+1); hashTable[x]=false;//處理完了p[index]為x 的子問題 } } } int main() { n=8; generateP(1); printf("合法的方案有:%d",count); }