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

本文介绍了N皇后问题的概念及求解算法,并通过实例演示了求解过程。提供了C++实现代码,可用于验证不同规模的N皇后问题解的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、什么是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  

以上结果可以作为测试案例验证程序。

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值