
实现n皇后问题的多种解法
从当前行i开始,逐个尝试将皇后放置在列j。 判断放置的位置是否合法: 若位置合法,将皇后放置在(i, j),并记录相关约束。 若上一行完成,则递归处理下一行;否则回退到上一行,尝试下一列。 生成列数组P[1..n],表示每一行放置的相应列号。 递归验证每个排列是否满足不在同一对角线的条件: 在stepVegas行处随机选择合法位置放置皇后。 放置成功后,后steps按传统回溯法完成。 若未能在stepVegas行找到合法位置,返回失败。 [皇后问题回溯法](https:// курс在线) [全排列枚举解法](https:// ) [Las Vegas思想优化](https:// )
发布日期:2021-05-20 07:54:52
浏览次数:23
分类:精选文章
本文共 3265 字,大约阅读时间需要 10 分钟。
n皇后问题解法与改进算法探讨
常规问题一:回溯法解法
回溯法思路
传统的n皇后问题可以通过回溯法解决。具体步骤如下:
- 列j是否已有皇后?
- 是否在同一45°对角线?判断条件为i + j是否已存在于diag45集合中。
- 是否在同一135°对角线?判断条件为i - j是否已存在于diag135集合中。
回溯法代码实现
#include#include #include #include using namespace std;void Backtracking(int N, int i, set col, set diag45, set diag135, vector placeResult, int &ans) { int j = 1; while (i <= N && i > 0) { while (j <= N) { if (!col.count(j) && !diag45.count(i + j) && !diag135.count(i - j)) { placeResult[i] = j; col.insert(j); diag45.insert(i + j); diag135.insert(i - j); i++; j = 1; break; } j++; } if (j > N) { j = Erase(i, col, diag45, diag135, placeResult); } if (i == N + 1) { ans++; for (int row = 1; row <= N; row++) { for (int col = 1; col <= N; col++) { if (col == placeResult[row]) { printf("√"); } else if (col != N) { printf(" "); } else { printf("\n"); } } } printf("\n"); } }}void Erase(int &i, set col, set diag45, set diag135, vector placeResult) { i--; int k = placeResult[i]; placeResult[i] = 0; col.erase(k); diag45.erase(i + k); diag135.erase(i - k); return k + 1;}// 该函数将皇后随机放置在前stepVegas行,后面的皇后按传统回溯法解决bool QueenLV(int N, set col, set diag45, set diag135, vector placeResult, int stepVegas) { int i = 1; int LP = 0; �� Coronation:
常规问题二:全排列枚举法
全排列枚举思路
使用全排列算法,生成所有可能的皇后位置排列。只需验证对角线约束即可。
- 检查每两个皇后之间的斜距是否为1。
全排列枚举代码
#include#include using namespace std;void generateP(vector &P, vector &isLegal, int n, int &ans, int index) { if (index == n + 1) { ans++; return; } for (int i = 1; i <= n; i++) { if (!isLegal[i]) { bool flag = true; for (int pre = 1; pre < index; pre++) { if (abs(index - pre) == abs(i - P[pre])) { flag = false; break; } } if (flag) { P[index] = i; isLegal[i] = true; generateP(P, isLegal, n, ans, index + 1); isLegal[i] = false; } } }}int main() { int n = 8; vector P(n + 1); vector isLegal(n + 1); int ans = 0; generateP(P, isLegal, n, ans, 1); printf("有%d种放置可能\n", ans); return 0;}
另一类问题:Las Vegas思想优化
优化思路
前stepVegas行采用随机放置,剩余行用传统回溯法解决。
优化结果分析
实验表明,stepVegas取略小于N的值时效果较好,步长如下:N = 8时,stepVegas = 7N = 15时,stepVegas = 13
这种方法相比纯回溯方法平均所需时间较少。
运行示例
如N=8,stepVegas=7与stepVegas=8的对比结果表明,stepVegas=7的平均首次成功所需时间更短。
扩展阅读
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2025年04月26日 15时04分29秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
MD5加密
2025-04-13
MD5的算法(C)
2025-04-13
Mdrill 测试数据写入程序
2025-04-13
Mean-Shift聚类方法
2025-04-13
Meanshift,聚类算法
2025-04-13
media="screen"啥意思?
2025-04-13
media=screen是什么意思 有什么用?
2025-04-13
mediawiki
2025-04-13
MegaCli查看RIAD相关信息
2025-04-13
MEGER sentence in oracle
2025-04-13
Meikade开源项目常见问题解决方案
2025-04-13
Member var and Static var.
2025-04-13
Membership学习(二)membership入门[xgluxv]
2025-04-13
Memcache 查看列出所有key方法
2025-04-13
memcached——分布式内存对象缓存系统
2025-04-13
memcached分布式部署
2025-04-13
Memcached对象缓存详解
2025-04-13
Memcached常用操作
2025-04-13