八皇后问题

耗尽温柔 提交于 2019-12-19 19:53:11

八皇后问题。是一个古老而著名的问题。是回溯算法的典型案例。

该问题是国际西洋棋棋手马克斯·贝瑟尔于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皇后的问题。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!