题目描述
在 N\times NN×N 的方格棋盘放置了 NN 个皇后,使得它们不相互攻击(即任意 22 个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成 4545 角的斜线上。你的任务是,对于给定的 NN,求出有多少种合法的放置方法。
输入描述
输入中有一个正整数 N≤10N≤10,表示棋盘和皇后的数量
输出描述
为一个正整数,表示对应输入行的皇后的不同放置数量。
输入输出样例
示例 1
输入
5
输出
10
不用输出棋盘时:
#include<stdio.h>
#include<math.h>
//对于N行N列的棋盘,需要放N个皇后。有sum种合法的放置方法
int sum,n;
int x[20]; //存放每行对应的列
bool vis[20],flag; //flag:标记当前位置是否合理
void dfs(int t)
{
if(t>n)
{
sum++;
return;
}
else
{
for(int i=1;i<=n;i++)//列举每列
{
if(vis[i]==false)
{
flag=true;
for(int k=1;k<t;k++) //check范围:1~t-1行
{
//如果在同一列或者对角线上 ,则该位置不合理
if(x[k]==i || abs(t-k)==abs(i-x[k])) //当前坐标(t,i) ,之前坐标(k,x[k])
{
flag=false;
break;
}
}
if(flag)
{
x[t]=i; //为每行选一个列
vis[i]=true;
dfs(t+1);
vis[i]=false;
}
}
}
}
}
int main()
{
while(true)
{
sum=0;
scanf("%d",&n);
if(n==0)
break;
dfs(1);
printf("%d\n",sum);
}
return 0;
}
需要输出棋盘时:
//方法1
#include<stdio.h>
#include<math.h>
#include<bits/stdc++.h>
using namespace std;
//对于N行N列的棋盘,需要放N个皇后。有sum种合法的放置方法
int sum,n;
int x[20]; //存放每行对应的列
bool vis[20],flag; //flag:标记当前位置是否合理
char a[111][111]; //输出棋盘
void dfs(int t)
{
if(t>n)
{
sum++;
for(int i = 1; i <= n; i ++)
{
for(int j=1;j<=n;j++)
printf("%c",a[i][j]);
printf("\n");
}
cout << endl;
return;
}
else
{
for(int i=1;i<=n;i++)//列举每列
{
if(vis[i]==false)
{
flag=true;
for(int k=1;k<t;k++) //check范围:1~t-1行
{
//如果在同一列或者对角线上 ,则该位置不合理
if(x[k]==i || abs(t-k)==abs(i-x[k])) //当前坐标(t,i)
{
flag=false;
break;
}
}
if(flag)
{
x[t]=i; //为每行选一个列
a[t][i] = 'Q';
vis[i]=true;
dfs(t+1);
vis[i]=false;
a[t][i] = '.';
}
}
}
}
}
int main()
{
sum=0;
scanf("%d",&n);
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
a[i][j] = '.';
}
}
dfs(1);
printf("%d\n",sum);
return 0;
}
//方法2
#include <bits/stdc++.h>
#include<iostream>
using namespace std;
int n,sum;
char x[20][20];
int l[20],ug[20],ng[20];
//t行i列
void dfs(int t)
{
if(t > n)
{
sum++;
for(int i = 1; i <= n; i ++)
{
for(int j=1;j<=n;j++)
printf("%c",x[i][j]);
printf("\n");
}
cout << endl;
return ;
}
for(int i = 1; i <= n; i ++)
{
if(!l[i] && !ug[i + t] && !ng[i - t + n])
{
x[t][i] = 'Q';
l[i] = ug[i + t] = ng[i - t + n] = 1;
dfs(t + 1);
l[i] = ug[i + t] = ng[i - t + n] = 0;
x[t][i] = '.';
}
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
x[i][j] = '.';
}
}
dfs(1);
printf("%d",sum);
return 0;
}
多组输入时:
输入格式
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
输出格式
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8
5 0
Sample Output
1 92
10
int main()
{
while(true)
{
sum=0;
scanf("%d",&n);
if(n==0) //输入0时停止
break;
dfs(0);
printf("%d\n",sum);
}
return 0;
}