20150410 递归实现八皇后问题

20150410 递归实现八皇后问题

2015-04-10 Lover雪儿

十九世纪著名的数学家高斯1850年提出:

    在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意的连个皇后都不能处于同一行、同一列或者统一斜线,问有多少种摆法。

以下是其中一种解法,如图所示:

20150410 递归实现八皇后问题

 

    当年高斯先生没日没夜的计算,得出结论是76种。

    其实正确的结论是92中,此处我们就来编程计算一下正确的答案。

 

  1 //八皇后问题

  2 #include <stdio.h>

  3 

  4 static int count = 0;    //算法的总数

  5 

  6 //判断第row行第col列位置是否有危险,是否在其他皇后的攻击范围

  7 //没有危险,则返回真

  8 int NotDanger(int row, int col, int (*chess)[8]){

  9     int i, k; 

 10     int flag_1=0, flag_2=0, flag_3=0, flag_4=0, flag_5=0;

 11     //判断列的方向有没有危险 标志位flag_1

 12     for( i=0; i<8; i++)

 13     {

 14         if( *(*(chess + i)+ col) != 0)    //判断是否有棋子

 15         {

 16             flag_1 = 1;

 17             break;

 18         }    

 19     }

 20     //判断左上方有没有危险 标志位flag_2

 21     for(i = row, k = col; i>=0 && k>=0; i--, k--)

 22     {

 23         if(*(*(chess + i)+k) != 0)

 24         {

 25             flag_2 = 1;

 26             break;

 27         }

 28     }

 29     //判断右下方有没有危险 标志位flag_3

 30     for(i = row, k = col; i<8 && k<8; i++, k++)

 31     {

 32         if(*(*(chess + i)+k) != 0)

 33         {

 34             flag_3 = 1;

 35             break;

 36         }

 37     }

 38     //判断右上方有没有危险 标志位flag_4

 39     for(i = row, k = col; i>=0 && k<8; i--, k++)

 40     {

 41         if(*(*(chess + i)+k) != 0)

 42         {

 43             flag_4 = 1;

 44             break;

 45         }

 46     }

 47     //判断左下方有没有危险 标志位flag_5

 48     for(i = row, k = col; i<8 && k>=0; i++, k--)

 49     {

 50         if(*(*(chess + i)+k) != 0)

 51         {

 52             flag_5 = 1;

 53             break;

 54         }

 55     }

 56     if( flag_1 || flag_2 || flag_3 || flag_4 || flag_5){

 57         return 0;

 58     }else{

 59         return 1;

 60     }

 61 }

 62 

 63 //八皇后算法 row:起始行 col:列数 *chess[8]:指向棋盘每一行的指针

 64 void EightQueen(int row, int col, int (*chess)[8])

 65 {

 66     int chess_tmp[8][8], i, j;

 67     for(i = 0; i<8; i++){

 68         for(j = 0; j<8; j++){

 69             chess_tmp[i][j] = chess[i][j];

 70         }

 71     }

 72     //当指针走到了第八行时,说明已经计算好,打印出棋盘

 73     if( 8 == row){

 74         printf("第 %d 种方法:\n",count+1);

 75         for(i = 0; i<8; i++){

 76             for(j = 0; j<8; j++){

 77                 printf("%d ",*(*(chess_tmp+i)+j));

 78             }

 79             printf("\n");

 80         }    

 81         printf("\n\n");

 82         count++;

 83     }else{

 84         //判断这个位置是否有危险,是否在其他皇后的攻击范围

 85         //如果没有危险,继续往下判断,知道row = 8

 86         for( j=0; j<col; j++){

 87             if(NotDanger(row, j, chess_tmp)){        //判断是否危险

 88                 for(i = 0; i<8; i++){                //将整行所有的列赋值为0

 89                     *(*(chess_tmp + row)+i) = 0;

 90                 }

 91                 *(*(chess_tmp + row)+j) = 1;

 92                 EightQueen(row+1, col, chess_tmp);  //递归调用

 93             }

 94         }

 95     }

 96 }

 97 

 98 int main(void)

 99 {

100     int chess[8][8], i, j;

101 

102     //初始化八皇后的棋盘,1:放置皇后 0:没有皇后

103     for(i = 0; i<8 ; i++){

104         for(j = 0; j<8 ; j++){

105             chess[i][j] = 0;

106         }

107     }

108     

109     freopen("EightQueen.txt", "w", stdout); //重定向输出到out.txt文件中

110 

111     EightQueen(0 , 8, chess);

112     printf("总共有 %d 种解决方法\n\n",count);

113 

114     return 0;

115 }

 

 

运行成功后在当前文件夹生成一个文件EightQueen.txt,内容如下所示:

20150410 递归实现八皇后问题

20150410 递归实现八皇后问题

 

你可能感兴趣的:(八皇后)