递归法解决N皇后问题

                                                                            N皇后问题

题目:

在一个n*n的棋盘上面放置n个皇后,要使得任意两个皇后之间不能相互攻击,规则是任意两个皇后处在同一行,同一列或者同一斜线的位置上时,能够相互攻击,皇后可以走任意步。

分析

通过分析题目可以知道,若使任意两个皇后都不能互相攻击,那么就必须使得任意两个皇后不能处在同一行,同一列,同一斜线即可(隐藏条件,皇后不能处在同一点),我们可以把棋盘看成一个n*n的等差坐标系,假设当一个皇后放在了(i,j)位置上时,那么i行,j列上的所有左边都不能再放置新的皇后,同时再所有的经过(i,j)点的斜线也是不能够放置皇后,行和列好解决,关键是如何解决斜线,因为再坐标系当中,任意点与其同一斜线上的点所构成的图形均为正方形,该斜线即为正方形的对角线,那么根据正方形的性质可知,其四条边相等,所以可以得到(记斜线上的某一点为(x,y)):(x-i)的绝对值=(y-j)的绝对值,所以这是能否放置皇后的充要条件。

#include<cstdio>
#include<cmath>
int sum=0;
bool pd(int i,int *a) {
	if(i==0)
		return true;//刚开始棋盘没有任何棋子,所以条件都满足
	for(int k=0; k<i; k++) {
		//不在同一列,同一对角线,因为使用了一维数组,每一行只占用一个位置,所以不在同一行隐含在了里面
		if((a[k]==a[i])||(abs(i-k)==abs(a[i]-a[k])))
			return false;
	}
	//条件满足,返回true代表当前位置可以放置
	return true;
}
//输出
void print(int *a,int n) {
	for(int i=0; i<n; i++) {
		for(int j=0; j<n; j++) {
			if(j==a[i])
				//一维数组中的数据代表再第几列,一维数组的下表代表在第几行
				printf("@ ");//打印皇后棋子
			else
				printf("# ");//打印棋盘
		}
		printf("\n");
	}
	printf("\n");
}
int qj(int i,int *a,int n) {
	for(int j=0; j<n; j++) {
		a[i]=j;//当前位置放置棋子
		if(pd(i,a)) {//判断是否满足
			if(i==(n-1)) {//判断是否是棋盘的最后一行
				print(a,n);//是的话,输出当前结果
				sum++;//解法总数+1
			} else
				qj(i+1,a,n);//如果不是最后一行,则行数+1,递归继续执行
		} else
			//不满足像左移动一位,接着判断,因为一维数组是用来存放列左边的,所以j+1代表列+1
			continue;
	}
}
int main() {
	int n;
	scanf("%d",&n);
	int a[n];//定义一维数组存放皇后的列坐标 
	qj(0,a,n);
	printf("%d\n",sum);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值