递归求解八皇后问题

题目:
八皇后问题
在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法

递归思路:在第1行安全位置放一个棋子,在第2行安全位置放一个棋子,以此类推,直到八行都放了棋子,第9行时退出递归过程。

C++代码:

//八皇后问题
//在8*8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法
//思路:在第1行安全位置放一个棋子,在第2行安全位置放一个棋子,以此类推,直到八行都放了棋子,第9行时退出递归过程
#include<iostream>
using namespace std;
#define NUM 8

int Count = 0; //记录摆法个数

int notDanger(int r, int l, int chess[NUM][NUM]) //判断第r+1行、第l+1列的位置是不是安全位置
{
	int k = 0, i = 0, j = 0;
	int flag = 0;
	//判断列方向
	for (k = 0; k < NUM; k++)
	{
		if (chess[k][l] == 1)
		{
			flag = 1;
			break;
		}
	}
	//判断左上方
	for (i = r - 1, j = l - 1; i >= 0 && j >= 0; i--, j--)
	{
		if (chess[i][j] == 1)
		{
			flag = 1;
			break;
		}
	}
	//判断右下方
	for (i = r + 1, j = l + 1; i < NUM && j < NUM; i++, j++)
	{
		if (chess[i][j] == 1)
		{
			flag = 1;
			break;
		}
	}
	//判断左下方
	for (i = r + 1, j = l - 1; i < NUM && j >= 0; i++, j--)
	{
		if (chess[i][j] == 1)
		{
			flag = 1;
			break;
		}
	}
	//判断右上方
	for (i = r - 1, j = l + 1; i >= 0 && j < NUM; i--, j++)
	{
		if (chess[i][j] == 1)
		{
			flag = 1;
			break;
		}
	}
	if (flag == 1)
	{
		return 0;
	}
	else return 1;
}
//参数row表示起始行,当前摆放的行编号
//参数line表示总列数
//参数chess[][]表示棋盘
void EightQueen(int row, int line, int chess[NUM][NUM])
{
	int i, j;
	//注意这里要设置一个chess2,并用chess初始化,这样某一行找不到安全位置,回退到上一行找下一个安全位置时,上一次在上一行摆放皇后的结果不会影响找该行下一个安全位置的过程
	int chess2[NUM][NUM]; 
	for (int i = 0; i < NUM; i++) 
	{
		for (int j = 0; j < NUM; j++)
		{
			chess2[i][j] = chess[i][j];
		}
	}
	if (row == NUM) //起始行是第9行时,摆放结束,打印出结果
	{
		cout << "第" << Count + 1 << "个排列是:" << endl;
		for (i = 0; i < NUM; i++)
		{
			for (j = 0; j < NUM; j++)
			{
				cout << chess2[i][j] << " ";
			}
			cout << endl;
		}
		Count++;
	}
	else
	{
		for (j = 0; j < line; j++)
		{
			//判断位置是否有危险,如果没有危险继续往下行放,有危险继续在该行寻找安全位置
			if (notDanger(row, j, chess2))
			{
				for (i = 0; i < NUM; i++)//把该行所有位置置为0
				{
					chess2[row][i] = 0;
				}
				chess2[row][j] = 1;//仅chess[row][j]位置=1
				EightQueen(row + 1, line, chess2);
			}
		}
	}
}
int main()
{
	int chess[NUM][NUM], i, j; //chess代表棋盘
	for (i = 0; i < NUM; i++) //棋盘初始化为0,放皇后为1
	{
		for (j = 0; j < NUM; j++)
		{
			chess[i][j] = 0;
		}
	}
	EightQueen(0, NUM, chess);
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值