N皇后问题-回溯算法-C

问题描述:n皇后问题:在N行N列的棋盘上放置不能互相攻击的N个皇后。根据国际象棋规则,处在同一行或同一列或同一斜线上的皇后可以互相攻击。N皇后问题的解满足以下条件:棋盘每行均放置一个皇后,且任何2个皇后不在同一列,也不在同一斜线上。
图片取自百度百科
一般首先想到用二维数组进行求解,但因为皇后不能出现在同一行,所以本题,使用一维数组求解。回溯也需运用递归,深度搜索思想。满足条件就进行下一步,直到完成一种解法,或不满足条件,跳转到回溯点,进行下一步,以此类推。
代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define n 4//皇后个数
int a[n];//皇后不能在同一行,所以简化为用一维数组存储皇后所在列
int sum = 0;//计算满足条件数
int b[n][n];//存储每种方法

//检查放置位置是否满足条件,皇后不能出现在同一列,同一行,及对角线(斜率为正负1的斜线)
bool Check(int c, int r)
{
	for (int i = 0; i < c; i++)
	{
		if (r == a[i] || abs(c - i) == abs(r - a[i]))//此解法已经排除同一行的情况,所以只用判断是否同一列,和斜线,斜线借助abs()绝对值来处理
			return false;
	}
	return true;
	
}
void Queen(int k)
{
	if (k == n)//放置完成
	{
		sum++;//计数加一
		//这一段是为了输出放置矩阵
		printf("放置方法:\n");
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
				printf("%d", b[i][j]);
			printf("\n");
		}
		printf("\n");
		//
		return;
	}
		
	for (int i = 0; i < n; i++)
	{
		
		if (Check(k, i))
		{
			//k表示放置皇后的行数,i表示该行皇后放置的列数,即第k行的皇后放置在第i列
			a[k] = i;
			b[k][i] = 1;//放置后,在矩阵中置1
			Queen(k + 1);
			b[k][i] = 0;//若无法放置完成,返回回溯点,则把当前位置置0,开始下一位置放置
		}		
	}
		

}
int main()
{
	memset(b, 0, sizeof(b));//该方法是初始化数组
	Queen(0);
	printf("%d皇后问题的放置方法共有:%d种\n", n,sum);
	system("PAUSE");
	return 0;
}

示例输入输出:
在这里插入图片描述
学习中,欢迎交流

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值