回溯法求解n皇后问题

皇后问题:

由n*n个方块排成n行n列的正方形称为“n元棋盘”。如果两个皇后位于棋盘上的同一行或同一列或同一对角线上,则称她们为互相攻击,现要求找使N元棋盘上的n个皇后互不攻击的所有布局。

假设棋盘上每一行放置一个皇后,分别用自然数0,1,2,.......,n-1。

首先定义一个长度为n的一维数组q,其中每一个元素去q[i](i=0,1,2,.......,n-1),随时记录第i行皇后所在的列数。

初始时,先将各皇后放在各行的第0列。即数组q的初值为:q[i]=0, i=0,1,2,.......,n-1 

另外第i行与第j行上的皇后在某一对角线上的条件为去|q[i]-q[j]|=|i-j|;而它们在同一列的条件为q[i]=q[j];


回溯法算法步骤如下:

对于第i行的皇后,假设前i-1个皇后互相不攻击,现在来安排第i个皇后使它与前面n-1个皇后互相不攻击就可以了。

【1】q[i]=n时,表示最后一列也搜索结束,无法安排第i行的皇后,令q[i]=0,回退一行,考虑重新安排第i-1行的皇后,使第i-1行的皇后向右搜索q[i-1]=q[i-1]+1;找到使第i-1行与前i-2行互不攻击的下一个位置,如果退回到第-1行(实际没有这一行),表示搜索结束,退出。

2】当q[i]<n,由于初始q[i]=0;从第0列开始向右搜索,,需要检查第i行上的皇后与前面的从第0行到第i-1均不互相攻击,才算成立,可以考虑下一行的皇后即i=i+1;若不成立,q[i]=q[i]+1,重复前面的步骤。

3安排好了第n-1行的皇后,说明搜索到了一个n皇后互不攻击的布局,可将其保存输出。然后将第n-1行皇后向后移动,即q[n-1]=q[n-1]+1,重复上述步骤,搜索一个皇后布局。

具体实现代码

#include "iostream"
#include <cmath>
using namespace std;
bool place(int k,int*q)//考察皇后k放置在x[k]列是否发生冲突
{
	int i;
	for(i=0;i<k;i++)
		if(q[k]==q[i]||abs(k-i)==abs(q[k]-q[i]))
			return false;
	return true;
}

void n_queen(int n,int*q)
{
	int k=0;
	while(k>=0)
	{
		while(q[k]<n&&!place(k,q))
				q[k]++;
		if(q[k]==n)
			{q[k--]=0;q[k]++;}
		else
			if (k==n-1)
			{
				for(int i=0;i<n;i++)
					cout<<q[i]<<' ';
				cout<<endl;
				q[k]++;
			} 
			else
			{
				k++;
			}		
	}
}

void main(void)
{
	int n;
	cin>>n;
	int* q=new int[n];
	for(int i=0;i<n;i++)
		q[i]=0;
	n_queen(n,q);
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值