HDU 2553 N皇后问题(详细题解)

这是一道深搜题目!问题的关键是在剪枝。

下面我们对问题进行分析:

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

将此表列出我们就应该知道在()方向上的数据的行和列的特点了,及   在 ()方向上  列 + 行 的和是相等的。

知道数据怎么处理就可以解决问题了。

下面附上参考代码:


 1 #include<iostream>
2 #include<cstring>
3 #include<cmath>
4 using namespace std;
5 int vis[3][50], P[15];//三个方向 ↑在此三个方向都不能有皇后
6 int n, sum;
7
8 void DFS(int row);
9
10 int main()
11 {
12 for(n = 1; n <= 10; n++)//先打表不然会超时的
13 {
14 memset(vis,0,sizeof(vis));
15 sum = 0;
16 DFS(1);
17 P[n] = sum;
18 }
19 while(scanf("%d",&n), n)
20 {
21 printf("%d\n",P[n]);
22 }
23 return 0;
24 }
25
26 void DFS(int row)
27 {
28 int i;
29 if(row == n + 1)//已经够n行了
30 {
31 sum ++;
32 return ;
33 }
34 for(i = 1; i <= n; i++)
35 {
36 if(vis[0][row-i+n] == 0 && vis[1][i] == 0 && vis[2][row+i] == 0)
37 {//不会回溯的同学要好好看看学习学习
38 vis[0][row-i+n] = vis[1][i] = vis[2][row+i] = 1;//变值
39 DFS(row + 1);//深搜
40 vis[0][row-i+n] = vis[1][i] = vis[2][row+i] = 0;//回溯
41 }
42 }
43 }

HDU 2553 N皇后问题(详细题解),布布扣,bubuko.com

时间: 2024-08-03 15:29:37

HDU 2553 N皇后问题(详细题解)的相关文章

HDU 2553 N皇后问题 --- 经典回溯

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2553 DFS+回溯 /* HDU 2553 N皇后问题 --- 经典回溯 */ #include <cstdio> #include <cstring> const int maxn = 15; int cnt, n; bool visit[3][maxn*2];//3个数组分别标记列,y+x斜线,y-x斜线是否冲突 注意要*2 /* 从第r行开始满足条件地放置皇后 r表示行(从0开

HDU 2553 N皇后问题 (搜索DFS)

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7743    Accepted Submission(s): 3481 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求

HDU 2553 N皇后问题(深搜DFS)

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 772   Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.你的任务是,对于给定的N,求出

HDU 2553 N皇后问题(递归深搜)

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8525    Accepted Submission(s): 3802 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求

[HDU 2553]--N皇后问题(回溯)/N皇后问题的分析

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2553 N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.你的任务是,对于给定的N,求出有多少种合法

HDU 2553(N皇后)(DFS)

http://acm.hdu.edu.cn/showproblem.php?pid=2553 i表示行,map[i]表示列,然后用DFS遍历回溯 可以参考这篇文章: http://blog.csdn.net/cambridgeacm/article/details/7703739 1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 #include <cstdlib> 5 #inc

HDU - 2553 N皇后问题(dfs)

题意:每行放一个棋子,棋子不能在同一行同一列,对角线. 这道题关键在剪枝.剪枝完了就是递归咯. 剪枝: (a[i]数组里面装选择的列). 某一行的a[i]不能和a[n]冲突,所以有以下4个需要判断的条件: a.行与行之间不能冲突,但是因为我们就是每一行求一个皇后位置,所以肯定不会冲突,不需要考虑啦. b.列与列直接不能冲突,a[n]!=a[i]. c.不在同一对左角线,a[n]-a[i]!=n-i. d.不在同一对右角线,a[n]-a[i]!=-(n-i). 然后c和d合并一下就是abs(a[n

hdu 2553 N皇后问题 经典搜索,DFS解法

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10239    Accepted Submission(s): 4609 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,

[ An Ac a Day ^_^ ] hdu 2553 N皇后问题 搜索

曾经想过一天一AC 坚持下来的确不容易额 (我是没坚持下来 尽量以后坚持…… 经典的N皇后问题 搜索的入门问题 学了这么久竟然一直没敲过 今天敲一下…… 这道题也不是很简单额 纯暴力就超时了 要打一下表…… 而且有一个小的优化 每次判断是否合理不用铺满图再判断 只需要判断当前放皇后的位置的上方 左上和右上有没有皇后就可以了 自己想也不好想-_-|| 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm>