本文共 1810 字,大约阅读时间需要 6 分钟。
解决八皇后问题的方法主要有两种:递归解法和回溯解法。以下是两个方法的实现代码及详细说明:
#include#include #define M 8 // 存在8个皇后bool check(int *c, int k) { int i = 0; for (i = k - 1; i >= 0; i--) { if (c[i] == c[k] || (c[i] - c[k] == i - k) || (c[i] + i == c[k] + k)) { return false; } } return true;}void display(int *c, int n) { int i = 0, j = 0; for (i = 1; i <= n; i++) { printf("%d ", c[i]); } printf("\n");}void q(int k) // 递归解法{ int i = 0; for (i = 1; i <= M; i++) { c[k] = i; if (check(c, k)) { if (k == M) // 到达最后一层,输出 { display(c, k); } else { q(k + 1); // 向下搜索 } } c[k] = 0; }}void qt(int k) // 回溯解法{ while (k >= 1) { while (c[k] < 0) { k--; } if (k == 1) { break; } int i = c[k - 1], j = k; k--; if (i <= j) { c[k] = c[k - 1]; c[k - 1] = -1; k++; } }}int main(void) { q(1); // 非递归 qt(1); // 递归 return 0;}
递归解法采用深度优先搜索的方式进行,适用于问题结构分明的情况。具体步骤如下:
q(int k)
:递归深度为k,依次尝试在第k行放置皇后。 check
函数,判断当前皇后是否与之前放置的皇后产生攻击。display
函数输出当前解。回溯解法在每一步放置皇后后进行全面检查,剪枝不合法的情况,提高效率。具体步骤如下:
c[20]
,用于存储皇后位置。qt(int k)
:从第k行开始尝试放置皇后。 递归解法:代码简单易读,容易实现,逻辑直观。缺点是:在解决复杂问题时,可能效率不高,且难以处理较大规模的棋盘。
回溯解法:采用分治策略,较早剪枝,效率较高。优点是:代码结构复杂,搜索更深入,在某些复杂问题中表现优异。
check
不仅检查列和行,还检查对角线的冲突,确保每一步都正确。通过以上两种策略,可以有效地解决八皇后问题,并根据需求选择合适的解法。
转载地址:http://ymzmz.baihongyu.com/