八皇后问题

来源:互联网 发布:淘宝如何搜电棍 编辑:程序博客网 时间:2024/05/18 02:02

八皇后问题描述:在8*8的棋盘中,每行放一个棋子需要保证,任何两个棋子都不占据棋盘上同一行、或者同一列、或者同一对角线。

该问题简单的解法是回溯法(其实下面算法也包含的剪枝)。回溯法:它的求解过程实质上是一个先序遍历一颗”状态树“的过程,只是这颗状态树不是遍历前预先建立的,而是隐含在遍历过程中。

怎样用回溯法解,先看一下四皇后的解状态转换图,(四皇后与八皇后原理一样,只是皇后数不一样)。


求解皇后的合法布局的过程即为在上述约束条件下下根遍历上述状态树的过程。当遍历到一个节点时,判断该节点是否已得到一个完整的布局,若是,输出该布局,若不是,依次先根遍历满足约束条件的各棵子树,首先判断该节点布局是否合法,若合法先根遍历其子节点,否则剪去该子树的分支。


实现代码如下:


bool judge(int array[8][8], int row, int col, int n){//棋盘是N*N,判断第row行,col列,皇后布局是否合理if (row == 0)return true;else {//同一列判断是否合理for (int i = row - 1; i >= 0; i--){if (array[i][col] ==1)return false;}//向左上对角线方向判断for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){if (array[i][j] == 1)return false;}//向右上对角线方向判断for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++){if (array[i][j] == 1)return false;}}return true;}void Trial(int array[8][8], int i, int n){if (i >= n) {for (int j = 0; j < n; j++) {for (int k = 0; k < n; k++) {cout<< array[j][k] << " ";}cout <<endl;}cout << endl;}else {for (int j = 0; j < n; j++) {array[i][j] = 1;if (judge(array, i, j, n)) Trial(array, i+1, n);array[i][j] = 0;}}}int main(int argc, char **argv){int array[8][8] = {0};//由于在命令行中不能看到全部结果,所以前面将结果输出重定向到filename.txt中freopen("filename.txt", "a+", stdout);Trial(array, 0, 8);system("pause");return 0;}