八皇后问题

问题:国际象棋中的皇后,可以横向、纵向、斜向移动。如何在一个8X8的棋盘上放置8个皇后,使得任意两个皇后都不在同一条横线、竖线、斜线方向上
思路:
使用递归回溯的方式。
所谓递归回溯,本质上是一种枚举法。这种方式从棋盘的第一行开始尝试摆放第一个皇后,摆放成功后,递归一层,再遵循规则在棋盘第二行来摆放第二个皇后。如果当前位置无法摆放,则向右移动一格再次尝试,如果成功,则继续递归一层,摆放第三个皇后……
如果某一层看遍了所有格子,都无法成功摆放,则回溯到上一个皇后,让上一个皇后右移一格,再进行递归。如果八个皇后都摆放完毕且符合规则,那么就得到了其中一种解法。
解决八皇后问题,可以分为两个层面:
1.找出第一种正确摆放方式,也就是深度优先遍历。
2.找出全部的正确摆放方式,也就是广度优先遍历。

深度优先遍历:

#include <iostream>
#include <string>
using namespace std;

//棋盘格子的范围,以及皇后数量
const int MAX_NUM = 8;
//二维数组作为棋盘
int chessBoard[MAX_NUM][MAX_NUM] = {0};

//检查落点是否符合规则
bool check(int x, int y)
{
	for (int i = 0; i < y; i++)
	{
		//检查纵向
		if (chessBoard[x][i] == 1)
			return false;

		//检查左侧斜向
		if (x - 1 - i >= 0 && chessBoard[x - 1 - i][y - 1 - i] == 1)
			return false;

		//检查右侧斜向
		if (x + 1 + i < MAX_NUM && chessBoard[x + 1 + i][y - 1 - i] == 1)
			return false;
	}
	return true;
}

//递归回溯
bool settleQueen(int y)
{
	//行数超过8,说明已经找出答案
	if (y == MAX_NUM)
		return true;

	//遍历当前行,逐一格子验证
	for (int i = 0; i < MAX_NUM; i++)
	{
		//为当前行清零,以免回溯时出现脏数据
		for (int x = 0; x < MAX_NUM; x++)
		{
			chessBoard[x][y] = 0;
		}
		//检查是否符合规则,如果符合,更改元素值并进一步递归
		if (check(i, y))
		{
			chessBoard[i][y] = 1;
			//递归如果返回true,说明下层已找到解法,无需继续循环
			if (settleQueen(y + 1))
				return true;
		}
	}
	return false;
}

void printChessBoard()
{
	for (int j = 0; j < MAX_NUM; j++)
	{
		for (int i = 0; i < MAX_NUM; i++)
		{
			cout << chessBoard[i][j];
		}
		cout << endl;
	}
}

int main()
{
	settleQueen(0);
	printChessBoard();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值