题解
- 根据皇后不能同行同列的性质可以知道,要在N*N棋盘上摆N个皇后则每行最多一个皇后,所以在暴力解的时候不需要每个皇后都遍历N *N种可能,只需要对该皇后对应行的N种可能遍历就行了(这里一层递归就代表一行,也就是一个皇后,以递归形参i来控制)。
- 直接用一个二维flag数组来标志棋盘上哪些格子可以放皇后,而每当在(i,j)放入一个皇后就要将其同排同列和上下斜线的格子flag置1,分别对应k = = i || r = = j || (k+r) = = (i+j) || (k-r) = =(i-j)。
题目
问题 F: N皇后问题
时间限制: 1 Sec 内存限制: 128 MB
提交: 1018 解决: 581
[提交][状态][讨论版]
题目描述
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
输入
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
输出
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
样例输入
1
8
5
0
样例输出
1
92
10
代码块
#include <iostream>
using namespace std;
int num;
void function(int i, int n, int flag[100][100])
{
if(i==n)
num++;
else
{
for(int j=0; j<n; j++)
{
if(!flag[i][j])
{
int flag1[100][100];//只需要将改变了的flag数组传入下一层递归,但并不需要改变这层递归中的flag数组,所以可以新建一个flag1作为改变了的flag的镜像传入下层。
for(int k=0; k<n; k++)
{
for(int r=0; r<n; r++)
{
if(k==i || r==j || (k+r)==(i+j) || (k-r)==(i-j))
flag1[k][r] = 1;
else
flag1[k][r] = flag[k][r];
}
}
function(i+1, n, flag1);
}
}
}
}
int main(void)
{
int n;
while(cin>>n)
{
if(n)
{
num = 0;
int flag[100][100];
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
flag[i][j] = 0;
function(0, n, flag);
cout<<num<<endl;
}
else
return 0;
}
}