题目描述
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;
}