八皇后問題 回溯法

問題描述:八皇后問題是數學家高斯於1850年提出的,這是一個典型的回溯算法的問題。八皇后問題的大意如下:
國際象棋的棋盤有8行8列共64個單元格,在棋盤上擺放8個皇后,使其不能互相攻擊,也就是說任意兩個皇后都不能處於同一行、同一列或同一斜線上。問總共共有多少種擺放方法,每一種擺放方式是怎樣的。
目前,數學上可以證明八皇后問題總共有92種解。
在這裏插入圖片描述
思路:保證8個皇后不能互相攻擊,即保證每一橫行、每一豎行、每一斜行最多一個皇后。
①不能在同一行,同一列②以及同一對角線(左右)
(1)對於①不能在同一行,同一列
意思即,每一橫行、每一豎行都只有一個皇后。我們暫時先撇開第②個條件,將8*8棋盤標上座標。我們討論其中的一種解法(我們規定橫縱座標都從1開始):

 - - - - - - - Q
 - - - Q - - - -
 Q - - - - - - -
 - - Q - - - - -
 - - - - - Q - -
 - Q - - - - - -
 - - - - - - Q -
 - - - - Q - - -

如果用座標表示就是:(1,8) (2,4) (3,1) (4,3) (5,6) (6,2) (7,7) (8,5)
將橫座標按次序排列,縱座標就是8/4/1/3/6/2/7/5。縱座標就是1~8的一個全排列。
規定橫座標就是從1-8,按照行遞增去給某列排皇后。相當於給每一行分別賦值滿足題中條件的列數。
(2)對於②以及同一對角線(左右):你知道的,兩個點之間連線的斜率絕對值爲1或者-1即爲同一斜行,充要條件是|x1-x2|=|y1-y2|(兩個點的座標爲(x1,y1)(x2,y2))。我們在輸出的時候進行判斷,任意兩個點如果滿足上述等式,則判爲失敗,不輸出。我們這裏把行當做,橫座標,把列當做縱座標。
綜上,其實這個問題可以簡化爲,找出縱座標等同於找出符合以上兩個條件(①和②)的1~n的全排列(實則是縱座標的值)。因爲,橫座標是1-n,不會變。
下面就好說了,如果還不知道全排列的思路,點擊下面這個:
生成1~n的全排列思路及代碼
該題基本和全排列是一樣的,只不過多了一個判定條件,那就是左右對角線。
下面附上AC代碼:

#include<cstdio>
#include<cmath>
const int maxn=11;
int count=0;
//P爲當前排列,hashTable記錄整數x是否已經在P中
int n,P[maxn] ,hashTable[maxn] = {false};
void generateP(int index)//index爲給第index行排皇后 
{
   if(index==n+1)
   {
	    count++;
	    return ;
   }
   for(int x=1;x<=n;x++)//給第index行,第x列排皇后 
   {
	    if(hashTable[x]==false)//第x列還沒有皇后
	    {
	       bool flag=true;// flag表示當前皇后不會和之前的皇后衝突
	       for(int pre=1;pre<index;pre++)// 遍歷index之前行的皇后
	       {//第index行的皇后的列號爲x,第pre行皇后的列號爲P[pre]
		        if(abs(index-pre)==abs(x-P[pre])) //橫座標之差==縱座標之差 
		        {
		          flag=false;// 與之前的皇后在一條對角線,衝突
		          break;
		    	}
	       }
	       if(flag)//如果可以把皇后放在第index行
	       {
		        P[index]=x;//令第index行皇后的列數爲x
		        hashTable[x]=true;//第x列已經被佔用
		        generateP(index+1);//遞歸處理第index+1行以及之後行的皇后(index+1~n) 
		        hashTable[x]=false;//遞歸完畢,還原第x列爲佔用狀態
	       }
	    }
   }
}
int main()
{
  n=8;
  generateP(1);
  printf("%d\n",count);
  return 0;
}

建議看這個題之前看一下,全排列,其實是一毛一樣的。只要和全排列聯繫上,這個題也就不是什麼事情啦。加油!

發佈了159 篇原創文章 · 獲贊 87 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章