八皇后问题求解

最近一直在学数据结构与算法,这东西挺烧脑的。。。有时候一个算法要想好几天,还不一定想的出来(可能本人智商比较低),但算法这东西特别神奇有趣。今天碰到的是八皇后问题,我先简单说下游戏规则,具体的大家可以百度百科里面看。就是有8个皇后,放进8*8的棋盘里,每个皇后的行,列两个对角方向不能出现皇后,否则就会发生打架。。。大概就是这回事,官方给出有92钟解法。看完题目后,你会发现用蛮劲直接使用多个嵌套的for循环对每输进去一个皇后的行,列,左右对角进行判断也可以实现,但是这样的复杂度就很高,肯定有比较简单的方法。虽然我自己琢磨了一个下午也没有想出了,但是看了别人的博文,理解学会别人的算法也是一种学习嘛。。我记得郝斌老师说过,算法这东西,如果一定时间你想不出来,就不用硬想,可能你想好阵子可以想出了,但是多费脑,多浪费时间啊,去学习别人的算法,理解了以后会用也是一种成功(可能也是本人的一种自我安慰把。。。哈哈)的确时间真的很重要,特别你面临毕业的时候,好像扯远了。。。。该博主利用的是递归的思想实现的八皇后问题,一起学习把,我把代码尽可能的注释的明白,也有可能有理解错误的地方,欢迎大家指出。。。下面废话不多说,下面附上实现代码和结果图。

#include"stdafx.h"
#include<iostream>
#include<cmath> 
#define N 8
using namespace std;

bool chessboard[N+1][N+1]={0};

//该函数接受3个参数(二维数组,检测当前行i,当前列j)的作用就是检查冲突,返回true即该位置没冲突,否则有冲突
bool check(bool chessboard[N+1][N+1],const int &i,const int &j)
{
	int m,n;
	for(m=1;m<=i-1;m++)
	{
		for(n=1;n<=N;n++)
		{
			if(chessboard[m][n]==1)
			{
				if(j==n||abs(m-i)==abs(n-j))//这里第一个是判断当前列是否有皇后,后面是判断该坐标的两个对角线上是否有皇后,本人认为这个是核心代码
					return false;
			}
		}
	}
	return true;//遍历完成后,返回true;
}


//该函数接受参数二维数组,作用是给确定好的二维数组放置皇后,当值为1时为没冲突皇后打印Q即Queen,不为1为冲突位不放皇后
void print(bool chessboard[N+1][N+1])//
{
	static int count=1;//用count计算有多少种解法
	count++;
	cout<<count<<"法"<<endl;
	for(int i=1;i<=N;i++)
	{
		for(int j=1;j<=N;j++)
		{
			if(chessboard[i][j]==1)
				cout<<"Q"<<" ";
			else
				cout<<"."<<" ";
		}
		cout<<endl;
	}
	cout<<endl;
}

//该函数的作用是对8个皇后的放置进行遍历
void trail(const int i)
{
	int j;
	if(i>N)//当i>N时表示8个皇后均已经放置完毕,输出当前的二维数组即为八皇后解
		print(chessboard);
	//否则,就先给每i行的元素赋1,然后每放完一次,就再放下一个皇后即递归该函数,该函数每次都对i皇后调用check函数,对放置位置进行检测
	else
	{
		for(j=1;j<=N;j++)
		{
			chessboard[i][j]=1;
			if(check(chessboard,i,j))//若返回true则表示该不能位置放皇后,将其值赋0
				trail(i+1);//检测完毕,放下一个皇后,当然该方法是一行一行检测,放皇后;
			chessboard[i][j]=0;
		}
	}

}

int main()
{
	trail(1);//这里将i赋1,表示从第一行,放置第一个皇后
	system("pause");
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值