http://acm.hdu.edu.cn/showproblem.php?pid=2553
这是一个经典的 dfs 回溯 的题目 同样这也是一道很坑很坑的题目 让我第一次接触了打表 。
所谓打表 就是在编译时间完成程序要进行的操作 在进行数据测试时 输入测试数据 然后在表中查找答案就可以了 。
题目要求任意两个皇后不能在同一行、同一列、或一个对角线上(主、副对角线),所以我们在放置一个皇后的时候 要判断它是否和其他皇后在同一行、同一列、同一角线上 如果是就不能放 不是就可以放 。
思路: 将皇后逐行放置 t表示 第几个皇后 也是第几行 这样我们就只需检查是否在同一列和对角线上 t条件 vis[t]==vis[i] 判断是否在同一列 条件 t-vis[t]==i-vis[i] || t+vis[t]==i+vis[i] 判断是(t,vis[t])he (i,vis[i])否在同一对角线上
AC代码:
#include<stdio.h>
#include<string.h>
int map[15][15];
int vis[15];
int n;
int count;
int a[11];
int judge(int t){
for (int i=0;i<t;i++){
if (vis[t]==vis[i]||t-vis[t]==i-vis[i]||t+vis[t]==i+vis[i])//判断是否在同一列 或 对角线
return 0;
}
return 1;
}
void search (int t){
if (t==n)//边界 所有皇后都已经放入棋盘中
{
count++;
return ;
}
else {
for (int i=0;i<n;i++){
vis[t]=i;//尝试把第t个皇后放入第i列
if (judge(t))//满足条件 继续下一层
{
search(t+1);
}
}
}
}
int main (){
for (n=0;n<11;n++)//打表
{
count=0;
memset(vis,0,sizeof(vis));
search(0);
a[n]=count;
}
while (scanf ("%d",&n)&&n){
printf ("%d\n",a[n]);
}
return 0;
}