2025/12/27 7:53:36
网站建设
项目流程
带数据库的网站怎么建,深圳手机报价网站,网络广告营销的特点,河南网络推广系统八皇后问题包含了回溯算法的核心思想 ——试探 - 回溯 - 剪枝#xff1a;同一行#xff1a;每行仅放 1 个皇后#xff08;按行遍历可天然避免行冲突#xff09;#xff1b;同一列#xff1a;需标记已占用的列#xff0c;避免重复使用#xff1b;对角线#xff1a;棋盘…八皇后问题包含了回溯算法的核心思想 ——试探 - 回溯 - 剪枝同一行每行仅放 1 个皇后按行遍历可天然避免行冲突同一列需标记已占用的列避免重复使用对角线棋盘有两条对角线方向左上→右下、右上→左下需分别标记占用状态。1. 回溯法的核心逻辑回溯法本质是一种 “暴力搜索的优化方案”通过深度优先搜索DFS试探每一种可能当发现当前路径无法达到目标时立即 “回溯” 到上一步尝试其他路径避免无效搜索。对于 8 皇后问题按行递归每行仅放 1 个皇后递归层数 棋盘行数8 层按列试探每一行遍历 8 列尝试在无冲突的列放置皇后冲突检测通过标记数组快速判断列和对角线是否占用O (1) 时间复杂度回溯恢复递归返回后撤销当前列和对角线的占用标记恢复棋盘状态为下一列试探做准备。2. 关键优化冲突检测的标记数组设计1列标记数组colUsed作用标记某一列是否已放置皇后大小8棋盘列数索引对应列号0~7状态colUsed[col] true表示第 col 列已占用。2对角线标记数组棋盘有两条对角线需分别设计标记数组左上→右下对角线记为 diag1同一对角线上的皇后满足row - col 常数取值范围row-col 的结果为 -7~78 行 8 列加 7 转为非负索引0~14故数组大小为 15索引计算diag1 row - col 7。右上→左下对角线记为 diag2同一对角线上的皇后满足row col 常数取值范围rowcol 的结果为 0~14天然非负数组大小为 15索引计算diag2 row col。通过这三个标记数组可在 O (1) 时间内完成冲突检测避免了暴力搜索中 “遍历已放皇后判断冲突” 的 O (n) 复杂度大幅提升效率。C代码实现#include iostream#include vectorusing namespace std;int count 0; // 统计解的数量vectorbool colUsed; // 标记列是否被占用大小8vectorbool diag1Used; // 标记左上→右下对角线大小152*8-115vectorbool diag2Used; // 标记右上→左下对角线大小15vectorvectorchar chessboard; // 存储棋盘状态Q皇后.空位// 回溯函数按行处理用标记数组快速判断冲突void backtracking(int row) {// 终止条件所有8行放完找到一个合法解if (row 8) {count; // 解数1// 打印当前合法解的棋盘cout 第 count 个合法解 endl;for (int i 0; i 8; i) { // 遍历每一行for (int j 0; j 8; j) { // 遍历每一列cout chessboard[i][j] ; // 打印当前格加空格更美观}cout endl; // 一行结束换行}cout endl endl; // 分隔不同解return;}// 遍历当前行的所有列for (int col 0; col 8; col) {// 计算对角线索引避免负数int diag1 row - col 7; // 范围0~14原row-col范围-7~77转正int diag2 row col; // 范围0~14天然非负// 冲突检测O(1)快速判断无冲突则继续if (!colUsed[col] !diag1Used[diag1] !diag2Used[diag2]) {// 标记当前位置为皇后chessboard[row][col] Q;// 标记当前列和对角线为占用colUsed[col] true;diag1Used[diag1] true;diag2Used[diag2] true;backtracking(row 1); // 递归处理下一行// 回溯撤销标记恢复状态为尝试当前行下一列做准备colUsed[col] false;diag1Used[diag1] false;diag2Used[diag2] false;chessboard[row][col] .; // 恢复当前位置为空位}}}/*...逐层递归直到row8→ row8 → 打印解 → return← 回到backtracking(7) → 撤销row7的状态 → 尝试下一列← 回到backtracking(6) → 撤销row6的状态 → 尝试下一列← 回到backtracking(0) → 撤销row0, col0的状态 → 尝试col1*/int main() {// 初始化标记数组默认false代表未占用colUsed.resize(8, false);diag1Used.resize(15, false);diag2Used.resize(15, false);// 初始化棋盘8行8列所有位置默认设为.空位chessboard.resize(8, vectorchar(8, .));backtracking(0); // 从第0行第一行开始回溯cout 剪枝优化回溯法解数 count endl; // 输出总解数92return 0;}