N皇后问题
Description:
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input:
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output:
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input:
1
8
5
0
Sample Output:
1
92
10
这题是经典的DFS问题。
题意很清楚,任意两个皇后不能再同一行同一列,同一斜线上。如下图:
刚看到这题,我并不打算用一个二维数组处理行列,没有必要浪费空间,一维已足够解决该问题了。数组下标表示行,数组存放的值为列(当然,反过来也是可以的)。一开始做错了,就百度了一下大牛们的写法,发现大体思路是对的,细节部分没处理好。下面修改后的代码:
<span style="font-size:14px;"><span style="font-size:14px;">#include<cstdio>
#include<cstdlib>
using namespace std;
int n,m,temp;
int map[15],ans[15];
void DFS(int ceng) //传入的参数是层数
{
int lie,k,flag;//列数lie
if(ceng == n+1)
{
temp++;
return ;
}
for(lie = 1; lie <= n; lie++)
{
map[ceng] = lie; //第ceng层的皇后放在第lie列
flag = 1;
for(k = 1; k < ceng; k++)
{
if( (map[k] == lie) || (abs(ceng-k) == abs(map[k]-lie)) )
//如果要放置的皇后与已经放置的皇后处于同一列或者在同一斜线,即为不符合的位列
{
flag = 0;
break;
}
}
if(flag) DFS(ceng+1);//该层可以存放,则进入下一层
}
}
int main(void)
{
for(n = 1; n <= 10; n++)
{
temp = 0; //临时存放结果
DFS(1); //从第一层开始
ans[n] = temp;
}
while(scanf("%d",&m) && m)
printf("%d\n",ans[m]);
return 0;
}</span></span>