[codeup] 2046 八皇后
2024-08-26 15:53:40
题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
样例输入
3
6
4
25
样例输出
25713864
17582463
36824175
思路
八皇后问题的答案有92个,首先按照字典序生成这92个答案,然后根据下标查询即可。生成八皇后直接按行的顺序生成八个全排列,这八个全排列即为八行中每行皇后的位置,也就是列号,然后检查满足限制条件即可。
简单的暴力生成版本:
int count = 0;
int n, p[maxn];
bool hash_table[maxn] = {false};
void generate_p(int index)
{
if (index == n + 1) { // 判断全排列满足条件
bool flag = true;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (abs(i - j) == abs(p[i] - p[j]))
flag = false;
}
}
if (flag)
count++;
return;
}
for (int x = 1; x <= n; x++) {
if (hash_table[x] == false) {
p[index] = x;
hash_table[x] = true;
generate_p(index + 1);
hash_table[x] = false;
}
}
}
由于某些全排列序列在前几个数出来时就可以判断是错误答案了,所以可以稍微优化以下代码,加上剪枝回溯的版本:
int count = 0;
int n, p[maxn];
bool hash_table[maxn] = {false};
void generate_p(int index)
{
if (index == n + 1) {
count++;
return;
}
for (int x = 1; x <= n; x++) {
if (hash_table[x] == false) {
bool flag = true; // 剪枝
for (int pre = 1; pre < index; pre++) {
if (abs(index - pre) == abs(x - p[pre])) {
flag = false;
break;
}
}
if (flag == true) {
p[index] = x;
hash_table[x] = true;
generate_p(index + 1);
hash_table[x] = false;
}
}
}
}
代码
#include <cstdio>
#include <algorithm>
const int maxn = 11;
int n, p[maxn];
bool hash_table[maxn] = {false};
int count = 0;
int solve[100] = {0};
void generate_p(int index)
{
if (index == n + 1) {
count++;
int tmp = 0;
for (int i = 1; i <= n; i++) {
tmp = tmp * 10 + p[i];
}
solve[count] = tmp;
return;
}
for (int x = 1; x <= n; x++) {
if (hash_table[x] == false) {
bool flag = true;
for (int pre = 1; pre < index; pre++) {
if (abs(index - pre) == abs(x - p[pre])) {
flag = false;
break;
}
}
if (flag == true) {
p[index] = x;
hash_table[x] = true;
generate_p(index + 1);
hash_table[x] = false;
}
}
}
}
int main()
{
int m, t;
n = 8;
generate_p(1);
scanf("%d", &m);
while (m--) {
scanf("%d", &t);
printf("%d\n", solve[t]);
}
return 0;
}
最新文章
- FFT
- HDOJ 4739 Zhuge Liang&;#39;s Mines
- OA项目之导出
- 自己实现一个高大尚的Android客户端
- 【BZOJ】【3473】字符串
- 1109. Conference(二分图)
- Linux使用locate命令定位文件
- 微软IIS服务器的最佳优化工具- IIS Tuner
- c# 操作word
- 樱花雨 www.yinghy.com
- 51单片机 Keil C 延时程序的简单(晶振12MHz,一个机器周期1us.)
- C# 静态类与非静态类、静态成员的区别分析
- 友情转发一则Erlang招聘广告
- Quartz.net 定时计划使用
- 笨方法学python--数字和数学计算
- 简单两步快速学会使用Mybatis-Generator自动生成entity实体、dao接口和简单mapper映射(用mysql和oracle举例)
- 八、Hadoop学习笔记————调优之Hive调优
- Python编程Day1——计算机组成与操作系统
- Spring MVC 异常处理 (九)
- 17 python 初学(迭代器)
热门文章
- Linux SNAT/DNAT简单理解与案例分析。
- C# 获取相对路径(绝对路径转相对路径)
- 使用 X-Frame-Options 防止被iframe 造成跨域iframe 提交挂掉
- phpmailer SMTP Error: Could not connect to SMTP host. 错误解决
- 【转】Bri&#39;s改装笔记
- 如何使用socket进行java网络编程(三)
- Day5 作业(完成)
- 手写数字识别---demo
- JavaWeb(HTML +css+js+Servlet....)
- Java并发编程之final域的内存语义