HDU 2553(DFS_A题)解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553
题意:NxN的棋盘,N个皇后,有多少种方法
思路:DFS
1.一行只能放一个皇后,所以我们一旦确定此处可以放皇后,那么该行就只能放一个皇后,下面的就不要再搜了。
2.每一列只能放一个皇后,所以我们下次搜索就不要再搜已经放过的皇后了。
3.斜的45°线也只能放一个。
综上如何才能最快速的确定一列和45°是否用过这个是个关键步骤,一旦此步骤确定我们就可以很快的进行搜索了。
我们用三个数组来保存他的每一个状态及(三个方向 ↖ ↑ ↗)
但是如果我们保存↑(每一列方向上的皇后)是非常容易保存的 但是保存( 这两个方向上的状态就不容易了↖ ↗)
再分析,在这个(↖)方向上的数据的行和列有什么特点
0 1 2 3 4
-1 0 1 2 3
-2 -1 0 1 2
-3 -2 -1 0 1
-4 -3 -2 -1 0
将此表列出我们就应该知道在(↖)方向上的数据的行和列的特点了,及 在 (↖)方向上 列 - 行 的差是相等的。
假如我们用数组保存负数肯定是不行的, 所以我们要加上 n,让他变为非负.
再分析,在这个( ↗)方向上的数据的行和列有什么特点
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
将此表列出我们就应该知道在(↗)方向上的数据的行和列的特点了,及 在 (↗)方向上 列 + 行 的和是相等的。
知道数据怎么处理就可以解决问题了。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int MAXN =10+10; int vis[3][MAXN]={{0,0}}; int tot=0; int ans[11+5]={0}; void search(int cur,int n){ if(cur==n) tot++; else for(int i=0;i<n;i++){ if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){ vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1; search(cur+1,n); vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; } } } int main(void){ for(int i=1;i<=10;i++){ for(int i=0;i<3;i++){ for(int j=0;j<11;j++){ vis[i][j]=0; } } tot =0; search(0,i); ans[i]=tot; } int n=0; while(~scanf("%d",&n)&&n!=0){ printf("%d\n",ans[n]); } return 0; }

浙公网安备 33010602011771号