搜索--N皇后 -- 回溯 -- DFS

题目描述

 

N皇后的排列,每行一个不冲突;N<=13。

 

 

输入要求

 

一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

 

 

输出要求

 

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

解的输出顺序为从上到下从左到右,小的优先输出

 

 

输入样例

6

 

 

输出样例

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

方法一:


#include<iostream>
#include<cmath>
using namespace std;
int N;//皇后数
int queenPos[100];//储存第k个(或者说第k行)皇后的列数,
int sum=0;
bool check(int k)//判断该行已选择的列号 与之前所有行已摆放的皇后比较,k j是行号
{
	for(int j=1;j<=k-1;j++)
	{//原来的位置(j,queenPos[j]),now position (k,i)
		if(queenPos[k]==queenPos[j]||abs(k-j)==abs(queenPos[j]-queenPos[k]))  
            return false;
	}
	return true;
}
 
void nQueen(int k)//第k个皇后摆放的位置,//第k-1个已经摆完的前提下摆放k
{
    if(k==N+1)//如果k个已经全部摆完,可以结束
    {
		sum++;
		if(sum<=3)
		{
			for(int i=1;i<=N;i++)
			{
				cout<<queenPos[i];
				if(i<N)
					cout<<" ";
			}
			cout<<endl;
		}
       
       return;
    }
    int j;
    for(int i=1;i<=N;i++)//求第k行,皇后拜访的列号i,从1到N列;,如果少了=,其实最后会少摆法!!
    {
         queenPos[k]=i;
         if(check(k)) nQueen(k+1);
    }
 
}
int main()
{
    cin>>N;
    nQueen(1);
	cout<<sum<<endl;
    return 0;
}
 

 

 

方法二:

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

int q[20];  // 每个皇后所在的列数
int solves = 0;  //解法 

void queen(int i, int n)
{
	if(i == n+1){  // 所有行全部走完,成功找到一种解法 
		solves++;
		if(solves <= 3){  // 只输出前三个解 
			for(int j=1; j<=n; j++){
				if(j == n){  // 格式控制,保证输出每行结尾处没有空格 
					cout << q[j];
					cout << endl;
				}	
				else
					cout << q[j] << " ";	
			}	
		}
		return ; 
	}
	
	else
		for(int col=1; col<=n; col++){  // 遍历第i行的每一列,找到可以放置皇后的位置 
			bool flag = true;
			for(int j=1; j<i; j++){  // 遍历前i行,判断列col是否冲突 
				if(col==q[j] || i+col==j+q[j] || i-col==j-q[j]){
					flag = false; 
					break;
				}	
			}
			
			if(flag){
				q[i] = col;
				queen(i+1, n);
			}
		}
}

int main()
{
	int n;
	memset(q,20,sizeof(q));
	cin >> n;
	queen(1, n);
	cout << solves << endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌新待开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值