八皇后问题

时间:2015-07-05 12:25:04   收藏:0   阅读:109

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

技术分享


解题思路:

我们按行判断,从上到下,如果某个位置有效,则置“Q”,无效则置“.”。主要的问题就是判断该位置是否有效,是否是危险位置(会产生冲突)。我们要判断本行、本列、此斜线上都没有皇后存在,此时才可以在这个位置上放置皇后。代码如下:

#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int queenNum=8;
int count=0;
vector<vector<string> > solveNQueens(int n);
void Nqueen(int row,int n,vector<vector<string>> &chess);
bool notDanger(int row,int j,vector<vector<string>> chess);
void main()
{
	vector<vector<string>> chess;
	vector<string> temp(queenNum,".");
	for (int i=0;i<queenNum;i++)
	{
		chess.push_back(temp);
	}
	chess= solveNQueens(queenNum);
}
vector<vector<string> > solveNQueens(int n) {
	vector<vector<string>> chess;
	vector<string> temp(queenNum,".");
	for (int i=0;i<queenNum;i++)
	{
		chess.push_back(temp);
	}
	Nqueen(0,queenNum,chess);
	cout<<"共有:"<<count<<"种分布"<<endl;
	return chess;
}

void Nqueen(int row,int n,vector<vector<string>> &chess)
{
	vector<vector<string>> chess2;
	chess2=chess;
	if (queenNum==row)
	{
		cout<<"第"<<count+1<<"种分布"<<endl;
		for (int i=0;i<queenNum;i++)
		{
			for (int j=0;j<queenNum;j++)
			{
				cout<<chess2[i][j];
			}
			cout<<endl;
		}
		cout<<endl<<endl;
		count++;
	}
	else
	{
		for (int j=0;j<n;j++)
		{
			if (notDanger(row,j,chess))//判断是否危险
			{
				for (int i=0;i<queenNum;i++)
				{
					chess2[row][i]=".";
				}
				chess2[row][j]="Q";	
				Nqueen(row+1,n,chess2);
			}
		}
	}
	
}

bool notDanger(int row,int j,vector<vector<string>> chess)
{
	bool flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;
	//判断列方向
	for (int i=0;i<queenNum;i++)
	{
		if (chess[i][j]!=".")
		{
			flag1=1;
			break;
		}
	}
	//判断左上方
	for (int i=row,k=j;i>=0&&k>=0;i--,k--)
	{
		if (chess[i][k]!=".")
		{
			flag2=1;
			break;
		}
	}
	//判断左下方
	for (int i=row,k=j;i<queenNum&&k>=0;i++,k--)
	{
		if (chess[i][k]!=".")
		{
			flag3=1;
			break;
		}
	}
	//判断右上方
	for (int i=row,k=j;i>=0&&k<queenNum;i--,k++)
	{
		if (chess[i][k]!=".")//
		{
			flag4=1;
			break;
		}
	}
	//判断右下方
	for (int i=row,k=j;i<queenNum&&k<queenNum;i++,k++)
	{
		if (chess[i][k]!=".")
		{
			flag5=1;
			break;
		}
	}
	if (flag1||flag2||flag3||flag4||flag5)
	{
		return false;
	}
	else
		return true;
}


代码中我们可以更改queueNum的值来计算n皇后的问题。

版权声明:本文为博主原创文章,未经博主允许不得转载。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!