博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[HDU 2553]--N皇后问题(回溯)/N皇后问题的分析
阅读量:5945 次
发布时间:2019-06-19

本文共 3311 字,大约阅读时间需要 11 分钟。

 

题目链接:

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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
 
Author
cgf
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:            
 
 
N皇后问题可以说是一个经典的回溯问题,看看下面的动画对皇后问题的求解有了一个大致的想法;
 
这里采用逐行放置的办法,那么就可以不用考虑皇后的横向攻击问题,只需要检查是否纵向和斜向攻击即可。
斜向判断条件"cur - vis[cur] == j - vis[j] || cur + vis[cur] == j + vis[j]",原理用一下两个表来说明
格子(x,y)的y-x标识了主对角线
 
 
0 1 2 3 4 5 6 7
-1 0 1 2 3 4 5 6
-2 -1 0 1 2 3 4 5
-3 -2 -1 0 1 2 3 4
-4 -3 -2 -1 0 1 2 3
-5 -4 -3 -2 -1 0 1 2
-6 -5 -4 -3 -2 -1 0 1
-7 -6 -5 -4 -3 -2 -1 0
 
 
 
 
 
 
 
 
 0  1  2  3  4 5 6 7
 1  2  3  4  5 6 7 8
 2  3  4  5  6 7 8 9
 3  4  5  6 7  8 9 10
 4  5  6  7  8  9 10 11
 5  6  7  8  9 10 11 12
 6  7  8  9 10 11 12 13
 7  8  9 10 11 12 13 14
格子(x,y)的x+y标识了副对角线
 
 
 
 
 
 
 
 
然后有一点特别坑的就是,这里虽然N<=10,但是是多组输入,刚开始一直超时,我习惯性的用cin输入,以为是这里的问题,
改了还是超时,各种改各种超时,最后想到也许输入100组N<=10,有重复的N,如果把每个值存贮了就不用算第二次了,改了下
总算过了。Orz~~~
 
代码如下:
1 #include 
2 #include
3 #include
4 using namespace std; 5 int n, vis[11], cnt, ans[11]; 6 void Search(int cur){ 7 if (cur == n) cnt++; 8 else for (int i = 0; i < n; i++){ 9 int flag = 1;10 vis[cur] = i;11 for (int j = 0; j < cur; j++){12 if (vis[cur] == vis[j] || cur - vis[cur] == j - vis[j] || cur + vis[cur] == j + vis[j]){13 flag = 0;14 break;15 }16 }17 if (flag) Search(cur + 1);18 }19 }20 int main(){21 memset(ans, -1, sizeof(ans));22 while (~scanf("%d", &n), n){23 //while (cin >> n, n){
24 cnt = 0;25 if (ans[n] != -1){26 printf("%d\n", ans[n]);27 continue;28 }29 Search(0);30 printf("%d\n", cnt);31 ans[n] = cnt;32 //cout << cnt << endl;33 }34 return 0;35 }
View Code

 

如果要输出排列情况,代码如下:

1 #include 
2 #include
3 #include
4 using namespace std; 5 int n, vis[11], cnt,T=1, ans[11]; 6 void Show(){ 7 for (int i = 0; i < n; i++){ 8 for (int j = 0; j < n; j++){ 9 if (j) cout << ' ';10 if (j == vis[i]) cout << char(3);11 else12 cout << '.';13 }14 cout << endl;15 }16 }17 void Search(int cur){18 if (cur == n){19 cout << "Case:" << T++ << endl;20 Show();21 cnt++;22 }23 else for (int i = 0; i < n; i++){24 int flag = 1;25 vis[cur] = i;26 for (int j = 0; j < cur; j++){27 if (vis[cur] == vis[j] || cur - vis[cur] == j - vis[j] || cur + vis[cur] == j + vis[j]){28 flag = 0;29 break;30 }31 }32 if (flag) Search(cur + 1);33 }34 }35 int main(){36 memset(ans, -1, sizeof(ans));37 while (cout<<"请输入皇后数:",cin >> n, n){38 T = 1;39 cnt = 0;40 Search(0);41 cout << "总排列方式:"<
<< endl;42 }43 return 0;44 }
View Code

 

转载于:https://www.cnblogs.com/zyxStar/p/4592219.html

你可能感兴趣的文章
ocserv服务器安装
查看>>
LVS-NAT实现Discuz负载均衡
查看>>
gnome 桌面 右击 open terminal 失效处理
查看>>
每天一个linux命令(58):rcp命令
查看>>
再论三层架构
查看>>
nginx代理多次302(nginx Follow 302)
查看>>
Jquery教程 1.jquery的基础选择器
查看>>
我的友情链接
查看>>
Highcharts和Hinghstock图表构造参数常用属性
查看>>
模糊测试工具Simple Fuzzer
查看>>
RabbitMQ入门(六) —— 持久化
查看>>
iOS12系统应用发送邮件中的附件
查看>>
我的友情链接
查看>>
LFS学习中遇到的错误
查看>>
lnmp安装脚本
查看>>
Yarn流程、Yarn与MapReduce 1相比
查看>>
SANS:2016年网络威胁情报现状调研报告
查看>>
xlsx格式Excel的处理
查看>>
mysql create database 指定utf-8编码
查看>>
maven 生成可执行的jar的多种方式
查看>>