题目链接:HDU 2553
题目描述:
Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
解题思路:
这是一道简单的深搜题目,搜索其实也算是一种遍历,找遍所有的结果,然后打表,输出需要的即可;
代码篇:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n;///方阵大小,也就是规模
int ans;///结果数量
int vis[12][12];///放皇后的位置标记
int row[12],col[12];///每一横行和每一竖列标记
int table[12];///结果打表
bool check(int i,int j)///检查横行竖列有无棋子(能否放下皇后)
{
int s,t;
if(row[i]) return false;///检查横行竖列有无棋子
if(col[j]) return false;
for(s=i+1,t=j+1; s<n&&t<n; s++,t++)///检查斜着的有无棋子
{
if(vis[s][t]) return false;
}
for(s=i-1,t=j-1; s>=0&&t>=0; s--,t--)
{
if(vis[s][t]) return false;
}
for(s=i-1,t=j+1; s>=0&&t<n; s--,t++)
{
if(vis[s][t]) return false;
}
for(s=i+1,t=j-1; s<n&&t>=0; s++,t--)
{
if(vis[s][t]) return false;
}
return true;///若无,则返回true
}
void dfs(int j)
{
if(j==n)
{
ans++;
return;///当j=n时,就意味着已经计算完最末尾的一行了
}
for(int i=0; i<n; i++)
{
bool flag=check(i,j);///检查能否放下皇后
if(flag)
{
vis[i][j]=1;
row[i]=1;
col[j]=1;
dfs(j+1);///能放下,则检查下一列
vis[i][j]=0;
row[i]=0;
col[j]=0;
}
}
}
int main()
{
for(int i=1; i<=10; i++)
{
memset(vis,0,sizeof(vis));///清空数组
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
n=i;///n为方格规模,防止越界
ans=0;
dfs(0);
table[i]=ans;
}
while(~scanf("%d",&n))
{
if(n==0) break;
printf("%d\n",table[n]);
}
return 0;
}