N皇问题(判断优化)

N皇后问题是一个dfs问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击),问有多少种摆法。

判断优化

对于n皇问题,回溯法我们很容易能够想到,但是这样的代码提交到oj上时间复杂度肯定是无法通过的,那么我们这里就介绍一种优化,判断优化。

在这里插入图片描述
如图,行为x,列为y;
对于同一根蓝色线上的矩阵元素,其行列相加(i+j)的值相同,对于同一根红色线上的矩阵元素,其行-列(x-y)值相同,但是由于是减法所以会出现负数,为了避免这个问题我们可以选择用N+i-j来表示红色线。
接下来,用bool数组来标记所有的对角线是否被某一皇后占据,再用一个数组来表示第y列是否有元素。
我的代码如下:

#include<iostream>
using namespace std;
bool lie[15],lf[30],ri[30];
int vis[15],n,i,sum;//第i个皇后(第i行),vis的值等于第几列 
bool check(int x,int y){//x行,y列 
	
	return lie[y]!=1&&lf[x+y]!=1&&ri[n+x-y]!=1?true:false;
}
void dfs(int x){
	if(x>n){
		sum++;
		if(sum<=3){
		
		for(int j=1;j<=n;j++)
		cout<<vis[j]<<' ';
		cout<<'\n';
	}
	return ;	}
	for(int k=1;k<=n;k++)
	{
		if(check(x,k))
		{
			vis[x]=k;
			lie[k]=1;
			lf[x+k]=1;
			ri[n+x-k]=1;
			dfs(x+1);
			lie[k]=0;
			lf[x+k]=0;
			ri[n+x-k]=0;
		}
		
	}
	return;
}
int main(){
	cin>>n;
	sum=0;
	dfs(1);
	cout<<sum<<'\n';
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值