1. 程式人生 > >一維陣列解決n皇后問題(暴力法)

一維陣列解決n皇后問題(暴力法)

    

以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);
}