八皇后问题
问题分析
1、问题解向量(x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8])
数组下标i表示皇后所在行号
数组元素x[i]表示皇后所在列号
2、约束条件
皇后不能同行,这里设的一维数组的表示,就显示约束了每行只能有一个皇后:x[i]=1,2,…,n
隐约束1:任意两个皇后不同列:x[i]!=x[j];
隐约束2:任意两个皇后不处于同一对角线:|i-j|!=|x[i]-x[j]|
3、思路
从棋盘第一行第一列、第二列依次放皇后,放一个皇后之后到棋盘下一行找符合条件的位置找到之后放皇后(在数组中记录皇后位置),然后再跳到下一行找相应的位置,每一次遍历所在行的所有列,找到符合条件的,最终如果在第8行找到了相应的放皇后的位置,那么说明找到一个解向量。
算法复杂度为o(n^3)。
实现代码
#include "stdafx.h" #include <math.h> #include <stdlib.h> /** *八皇后问题 *数组下标1-8表示,棋盘的第几行 *数组值x[i],表示棋盘的第几列 *从第一行第一列开始找,设其为皇后所在位,根据边界条件 */ int x[9];//这里从下标1开始方便理解 int sum = 0; void output(int arr[]); int main(); bool Bound(int k) { for (int i=1; i < k; i++) { if ((abs(i - k) == abs(x[k] - x[i])) || x[k] == x[i]) { return false; } } return true; } void Backtrack(int t) { if (t > 8) { ++sum; output(x); } else { for (int i = 1; i <= 8; i++) { x[t] = i; if (Bound(t)) Backtrack(t + 1); } } } void output(int arr[]) { for (int i = 1; i <= 8; i++) { printf("%d\n", arr[i]); } } int main() { Backtrack(1); printf("解sum=%d\n", sum); system("pause"); return 0; }