您的位置:首页 > 其它

N皇后问题解法及解的个数

2014-01-04 22:08 351 查看
一、什么是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

以上结果可以作为测试案例验证程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: