N皇后問題(八皇后問題)

八皇后問題,是一個古老而著名的問題,是回溯算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於1848年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。

在這裏我們解決的是N皇后問題,即在一個n*n的棋盤上,擺放n個皇后,使之不相互攻擊。問有幾種擺放方法(不考慮棋盤的對稱性):

對於8皇后問題,我們可以通過8重循環的回溯算法解決,但是對於N皇后,我們無法預知N的值,所以不能使用這種方法。

但是可以使用遞歸實現循環:每一次遞歸解決一行的皇后擺放位置,使之不與前幾行衝突,之後再遞歸調用自身確定下一行的位置。

代碼如下(C++):

#include <iostream>
using namespace std;

int N;                    //N個皇后
int queen_pos[100];       //每個皇后的位置,目前最大範圍是100
int num = 0;              //統計最終擺放位置方案的個數
void queen(int k);        //遞歸函數

int main()
{
	cin >> N;  //輸入N
      	queen(0); //從第0行開始擺放
	cout << num << endl;    
	system("pause");
	return 0;
}

/*
@brief:遞歸實現每一行皇后的擺放位置
@parameter:K:從第K行開始擺放
*/
void queen(int k)		
{
	if (k==N)        //擺滿N行輸出                                  
	{
		for (int i = 0; i < N; i++)
		{
			cout << queen_pos[i] + 1<<" ";  //列數+1,因爲棋盤從第一列開始
		}
		cout << endl;
		num++;         //統計量+1
	}
	for (int i = 0; i < N; i++)     //枚舉皇后所在的列數	
	{
		int j = 0;
		for (; j < k; j++ )      //是否與前幾行衝突
		{
                        //與前幾行同列 || 與前幾行在同一對角線上,則衝突
			if (queen_pos[j] == i || (abs(queen_pos[j] - i) == k - j))
				break;              //如果衝突,跳出,否定這個位置
		}
		if (j==k)           //如果不衝突
		{
			queen_pos[k] = i;      //確定這一行皇后的位置
			queen(k+1);            //遞歸進入下一行
		}
	}
}

以下爲用程序求出的所有8皇后的解(92種):

1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5
1 7 4 6 8 2 5 3
1 7 5 8 2 4 6 3
2 4 6 8 3 1 7 5
2 5 7 1 3 8 6 4
2 5 7 4 1 8 6 3
2 6 1 7 4 8 3 5
2 6 8 3 1 4 7 5
2 7 3 6 8 5 1 4
2 7 5 8 1 4 6 3
2 8 6 1 3 5 7 4
3 1 7 5 8 2 4 6
3 5 2 8 1 7 4 6
3 5 2 8 6 4 7 1
3 5 7 1 4 2 8 6
3 5 8 4 1 7 2 6
3 6 2 5 8 1 7 4
3 6 2 7 1 4 8 5
3 6 2 7 5 1 8 4
3 6 4 1 8 5 7 2
3 6 4 2 8 5 7 1
3 6 8 1 4 7 5 2
3 6 8 1 5 7 2 4
3 6 8 2 4 1 7 5
3 7 2 8 5 1 4 6
3 7 2 8 6 4 1 5
3 8 4 7 1 6 2 5
4 1 5 8 2 7 3 6
4 1 5 8 6 3 7 2
4 2 5 8 6 1 3 7
4 2 7 3 6 8 1 5
4 2 7 3 6 8 5 1
4 2 7 5 1 8 6 3
4 2 8 5 7 1 3 6
4 2 8 6 1 3 5 7
4 6 1 5 2 8 3 7
4 6 8 2 7 1 3 5
4 6 8 3 1 7 5 2
4 7 1 8 5 2 6 3
4 7 3 8 2 5 1 6
4 7 5 2 6 1 3 8
4 7 5 3 1 6 8 2
4 8 1 3 6 2 7 5
4 8 1 5 7 2 6 3
4 8 5 3 1 7 2 6
5 1 4 6 8 2 7 3
5 1 8 4 2 7 3 6
5 1 8 6 3 7 2 4
5 2 4 6 8 3 1 7
5 2 4 7 3 8 6 1
5 2 6 1 7 4 8 3
5 2 8 1 4 7 3 6
5 3 1 6 8 2 4 7
5 3 1 7 2 8 6 4
5 3 8 4 7 1 6 2
5 7 1 3 8 6 4 2
5 7 1 4 2 8 6 3
5 7 2 4 8 1 3 6
5 7 2 6 3 1 4 8
5 7 2 6 3 1 8 4
5 7 4 1 3 8 6 2
5 8 4 1 3 6 2 7
5 8 4 1 7 2 6 3
6 1 5 2 8 3 7 4
6 2 7 1 3 5 8 4
6 2 7 1 4 8 5 3
6 3 1 7 5 8 2 4
6 3 1 8 4 2 7 5
6 3 1 8 5 2 4 7
6 3 5 7 1 4 2 8
6 3 5 8 1 4 2 7
6 3 7 2 4 8 1 5
6 3 7 2 8 5 1 4
6 3 7 4 1 8 2 5
6 4 1 5 8 2 7 3
6 4 2 8 5 7 1 3
6 4 7 1 3 5 2 8
6 4 7 1 8 2 5 3
6 8 2 4 1 7 5 3
7 1 3 8 6 4 2 5
7 2 4 1 8 5 3 6
7 2 6 3 1 4 8 5
7 3 1 6 8 5 2 4
7 3 8 2 5 1 6 4
7 4 2 5 8 1 3 6
7 4 2 8 6 1 3 5
7 5 3 1 6 8 2 4
8 2 4 1 7 5 3 6
8 2 5 3 1 7 4 6
8 3 1 6 2 5 7 4
8 4 1 3 6 2 7 5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章