N皇后問題解法及解的個數

一、什麼是N皇后問題?

在n×n格的棋盤上放置彼此不受攻擊的n個皇后。按照國際象棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。n後問題等價於再n×n的棋盤上放置n個皇后,任何2個皇后不妨在同一行或同一列或同一斜線上。

二、算法


1、將第一個皇后放置在第一行的第一個空格里

2、對於第二行,從第一個空格開始尋找不與第一行的皇后衝突的空格。找到的第一個不衝突的空格是第2個。

3、對於第三行,這時已經找不到與之前放置的兩個皇后不衝突的空格了。把當前行恢復初始狀態,返回到上一行。

4、在當前行皇后所佔的空格之後尋找一個不與之前皇后衝突的位置。有兩種情況,如果找打了則把當前行的皇后移動到該位置,然後處理下一行。如果直到最後當前行的最後一個空格也沒有找合適的位置,則把當前行恢復初始狀態,繼續回溯到上一行。

5、把最後一個皇后成功安置在最後一行,代表找到了一種可行解。返回步驟4。

6、當需要回溯到第0行(表格之外)的時候代表已經找遍了所有可能的可行解。

三、4皇后解法圖解

第一步

Q

   

   

   

 

 

 

 

 

 

 

 

 

 

 

 

 第二步

Q

   

 

   

 

 

Q

 

 

 

 

 

 

 

 

 

 第三步 發現第三行沒有合適的位置了,於是將第二行皇后的位置移到下一個不衝突的位置

Q

   

   

 

 

 

 

Q

 

 

 

 

 

 

 

 

 第四步

Q

 

   

 

 

 

 

Q

 

Q

 

 

 

 

 

 

 第五步 發現第四行沒有合適的位置了,於是回溯到第二行,又發現第二行到頭了,於是繼續回溯到第一行。把第一行皇后的位置後移。

   

Q

   

 

 

 

 

Q

 

 

 

 

 

 

 

 

 第六步

 

Q

   

 

 

 

 

Q

Q

 

 

 

 

 

 

 

 第七步

 

Q

 

 

 

 

 

Q

Q

 

 

 

 

 

Q

 



四、程序

#include "stdafx.h"
#include <iostream>
using namespace std;

int n=0;
int arr[100];
bool place(int i)		//判斷能不能放置第N個皇后
{
	for(int j=0;j<i;j++)
		if(arr[j]==arr[i]||abs(arr[j]-arr[i])==abs(j-i))
			return false;
	return true;
}
int queue(int n)
{
	int solution=0;
	for(int i=0;i<n;i++)
		arr[i]=0;
	int k=1;
	while(k>=0)
	{
		while(!place(k)&&k<n)			//放置第N個皇后
			arr[k]=arr[k]+1;
		if(arr[k]<n&&k==n-1)				//排列完成一次
		{
			solution++;
			arr[k]=arr[k]+1;
		}
		else if(arr[k]<n&&k<n-1)			//排列完一個皇后
		{
			k=k+1;
			arr[k]=-1;
		}
		else								//當前皇后沒有合適的位置
		{
			arr[k]=0;
			k=k-1;
			arr[k]=arr[k]+1;
		}
	}
	
	return solution;
}
void main()
{
	while(1)
	{
		cout<<"Please input the queue number:"<<endl;
		cin>>n;
		if(n==-1)
			break;
		int x=queue(n);
		cout<<x<<" solution(s)"<<endl;
	}
	system("pause");
}

五、N皇后問題解的個數

n       solution(n)  
1       1  
2       0  
3       0  
4       2  
5       10  
6       4  
7       40  
8       92  
9       352  
10      724  
11      2680  
12      14200  
13      73712  
14      365596  
15      2279184  
16      14772512  
17      95815104  
18      666090624  
19      4968057848  
20      39029188884  
21      314666222712  
22      2691008701644  
23      24233937684440  
24      227514171973736  
25      2207893435808352  

以上結果可以作爲測試案例驗證程序。

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