【C++】队列式分支限界法解决n皇后问题

要求用队列式分支限界法求出n皇后问题的1个解
代码如下:

#include"LinkQueue.h"//包含队列类的头文件,这里就不放出了
#define max 10
struct STNode
{
	int i;//结点层次
	int* x;//结点的解向量
	STNode()
	{
		x = new int[max];
		i = 0;
		for (int j = 0; j < max;j++)
			x[j] = 0;
	}
	~STNode()
	{
		delete[]x;
	}
	STNode(const STNode& s)
	{
		x = new int[max];
		i = s.i;
		for (int j = 0; j < max;j++)
			x[j] = s.x[j];
	}
	STNode& operator=(const STNode& s)
	{
		x = new int[max];
		if (this != &s) {
			i = s.i;
			for (int j = 0;j < max;j++)
				x[j] = s.x[j];
		}
		return *this;
	}

};

class NQueensProblem
{
protected:
	int n;
	int* q;
public:
	NQueensProblem(int N);
	~NQueensProblem()
	{
		delete[]q;
	}
	bool Solve();
	int* GetSolution();
	bool Place(int,int, int*);
};
NQueensProblem::NQueensProblem(int N)
{
	n = N;
	q = new int[n + 1];
	for (int i = 0;i <= n;i++)
		q[i] = 0;
}

bool NQueensProblem::Place(int i, int c,int* x)
//i是当前行数,c是列数,判断能否放在c列
{
	if (i == 1)return true;
	for (int j = 1;j <i;j++)
		if ((c == x[j]) || (fabs(c - x[j]) == fabs(i - j)))
			return false;
	return true;
}
bool NQueensProblem::Solve()
{
	LinkQueue<STNode>queue;
	STNode e;
	e.i = 0;
	for (int j = 1;j <= n;j++)e.x[j] = 0;
	queue.EnQueue(e);
	while (!queue.IsEmpty())
	{
		queue.DelQueue(e);
		if (e.i == n) {
			for(int j = 1; j <= n; j++)
				q[j] = e.x[j];
			return true;
		}
		else {
			for(int j=1;j<=n;j++)//j为列数,依次试探
				if (Place(e.i + 1, j, e.x))
				{
					STNode t;//扩展结点
					t.i = e.i + 1;
					for (int j = 1;j <=e.i;j++)t.x[j] = e.x[j];
					t.x[t.i] = j;
					queue.EnQueue(t);
				}
		}
	}
	return false;
}
int* NQueensProblem::GetSolution()
{
	int *t = new int[n + 1];
	for (int i = 0;i <= n;i++) t[i] = q[i];
	return t;
}

主函数

#include <iostream>
using namespace std;
#include "NQueensProblem.h"	
int main()
{
	int n;

	cout << "Please enter the number of queens:" << endl;
	cin >> n;//输入皇后数目
	NQueensProblem nqp(n);		
	if (nqp.Solve())//有解
	{
		int* ans = nqp.GetSolution();//返回问题的解
		cout << "The solution is:" << endl;
		for (int i = 1; i <= n; i++)
			cout << "row " << i << ": " << ans[i] << endl;
		delete[]ans;
	}
	else
		cout << "No solutions!";

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值