八皇后问题

来源:互联网 发布:淘宝剑三升级代练 编辑:程序博客网 时间:2024/05/01 10:31
    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。百度百科解释

    

     一般看到这种图,大家第一感觉肯定是用一个二维数组来表示出坐标信息,但此处,感觉题目进行分析,8X8的棋盘上摆放8个皇后,且不能同行、同列和同一斜线上,那么也就是说每行最多一个皇后。因此我们仅用一个长度为8的数组就可以表示出皇后的位置信息,该数组的索引N即为第N行,索引对应的值即为第N行皇后所处的列数。

    另外,对于该问题,也不能简单的进行遍历,因为时间复杂度为8*8*8*8*8*8*8*8*8,8的8次方。换个角度:

    1,在第N行放置皇后,只需要判断前N-1行皇后的位置与第N行皇后的关系,那么剩下的8-N行在这个循环中是不需要判断的(因为此时剩下的行还没有皇后啊^_^)。如果第N行放置成功,则在此基础上尝试放置第N+1行的皇后;

    2,如果第N行放置失败,则要回溯到第N-1行,重新选择第N-1行皇后所处的列数。如果第N-1行依然放置失败,则再回溯到第N-2行,以此类推;

    3,如果第N行为最后一行了,则说明完全成功,打印整个棋盘。


#include <stdio.h>#include <malloc.h>#include <stdio.h>                #include <math.h>#include <string.h>#include <stdlib.h>// 打印整个阵列void printPos(const int *pos, const int cnt){#define QUEEN '#'#define NOT_QUEEN'*'// 记录共有多少组满足条件的组合。static int total = 0;printf("case %d:\n", ++total);for(int i = 0; i < cnt; ++i){for(int j = 0; j < cnt; ++j){if(pos[i] != j){printf("%c ", NOT_QUEEN);}else{printf("%c ", QUEEN);}}printf("\n");}printf("\n");}// 尝试在第row行插入的第col列插入值int tryInsertPos(int* pos, const int cnt, int row, int col){for(int i = 0; i < row; ++i){int otherRow = i;// row行之上的皇后所处的行数。int otherCol = pos[otherRow];// row行之上的皇后所处的lie数。// 不能在同一列。if(col == pos[otherRow]){return -1;}// 不能在对角线上。if(abs(col - otherCol) == abs(row - otherRow)){return -1;}}pos[row] = col;// 最后一行,已经满足条件了。if(cnt == row + 1){printPos(pos, cnt);return 0;}else{int ret = 0;// 尝试在下一行的各个位置放置皇后。for(int i = 0; i < cnt; ++i){ret = tryInsertPos(pos, cnt, row + 1, i);if(ret != 0){continue;}}return ret;}}int main(int argc, char** argv){int CNT = 8;if(argc == 2){CNT = atoi(argv[1]);}// 数组的索引为皇后所在的行数,索引对应的值表示该皇后对应的列数。// 如pos[1] = 2,则表示在第二行第三列存在皇后。int *pos = (int*)malloc(sizeof(int) * CNT);if(NULL == pos){printf("line %d malloc error\n", __LINE__);return -1;}memset(pos, 0, sizeof(int) * CNT);//tryInsertPos(pos, CNT, 0, 0);for(int i = 0; i < CNT; ++i){tryInsertPos(pos, CNT, 0, i);}free(pos);return 0;}



版权声明:本文为博主原创文章,未经博主允许不得转载。

 

0 0
原创粉丝点击