HDU 2553 N皇后问题(2种详细题解)
来源:互联网 发布:mac怎么看运行的程序 编辑:程序博客网 时间:2024/06/01 10:52
N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5654 Accepted Submission(s): 2555
你的任务是,对于给定的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
将此表列出我们就应该知道在(↗)方向上的数据的行和列的特点了,及 在 (↗)方向上 列 + 行 的和是相等的。
知道数据怎么处理就可以解决问题了。
#include<bits/stdc++.h> using namespace std; const int maxn = 25; int ans[maxn], n, sum; bool vis[3][maxn]; void dfs(int cur) { if(cur == n+1) { sum++; return ; } for(int i = 1; i <= n; i++) { if(!vis[0][i] && !vis[1][i-cur+n] && !vis[2][i+cur]) { vis[0][i] = vis[1][i-cur+n] = vis[2][i+cur] = 1; dfs(cur+1); vis[0][i] = vis[1][i-cur+n] = vis[2][i+cur] = 0; } } } int main(void) { for(n = 1; n <= 10; n++) { memset(vis, 0, sizeof(vis)); sum = 0; dfs(1); ans[n] = sum; } while(cin >> n, n) printf("%d\n", ans[n]); return 0; }
这道题最直接的思路就是枚举 暴力解决,但是显然是不行的。
所以只能用回溯。 基本思路 ,一行一行的放 皇后, 然后再递归判断是否与之前已放好的皇后有冲突,一旦有冲突,则不需要继续下一行的搜索,直接返回(省去不必要的枚举)。
另外关于这题,还有一点,我第一次交的时候TLE了,说明测试数据特别多。所以得先预处理(这个亏吃了很多次了,牢记牢记).
//八皇后问题 回溯法#include<stdio.h>int tot=0,row,line[10],n;int main(){ void search(int ); int a[11]; for(n=1;n<=10;n++) //之前就是没有这一步预处理,所以TLE了 TT { tot=0; search(0); a[n]=tot; } while(scanf("%d",&n)!=EOF&&n) printf("%d\n",a[n]); return 0;}void search(int row) //递归搜索可行解{ int i,j; if(row==n) tot++; //当row=n时,说明每一行的皇后都不冲突,即为可行解 else for(i=0;i<n;i++) { int ok=1; line[row]=i; //尝试把第row行的皇后放在i列上 for(j=0;j<row;j++) //检验是否与前面已放好的皇后冲突 { if(line[row]==line[j]||line[row]-row==line[j]-j||line[row]+row==line[j]+j) { ok=0; break; //,跳出最内层循环如果冲突,停止搜索,返回上一级递归回溯。回溯法高效的关键。 } } if(ok) search(row+1); }}
- HDU 2553 N皇后问题(2种详细题解)
- hdu 2553(N皇后问题)
- hdu 2553 N皇后问题(dfs)
- hdu 2553 N皇后问题(回溯)
- HDU 2553 N皇后问题(dfs)
- 【HDU】2553 - N皇后问题(dfs)
- HDU:2553 N皇后问题(深搜)
- 【HDU】-2553-N皇后问题(DFS)
- HDU 2553 N皇后问题(DFS)
- HDU 2553 n皇后问题(回溯)
- HDU 2553 n皇后问题(回溯)
- HDU 2553 N皇后问题(dfs)
- HDU 2553 N皇后问题
- HDU 2553 N皇后问题
- HDU 2553-N皇后问题
- hdu 2553 N皇后问题
- HDU-2553-N皇后问题
- Hdu 2553 N皇后问题
- 调试器GDB和Makefile
- OJ.189.素数判定
- c#第四章示例2
- Linux下的调试器GDB
- C#异步通信概念及应用浅析
- HDU 2553 N皇后问题(2种详细题解)
- LeetCode 432. All O`one Data Structure
- InSAR-DInSAR 技术细节(二) 干涉测量的条件(木有免费的午餐,以及晚餐))
- hdoj-【1175 连连看】
- 机器学习10大经典算法简介
- 12 IDE eclipse/Object
- java读取文件的几种方式
- JDBC编程中使用Result代替ResultSet
- JDBC连接数据库两种方式