Lover雪儿
想念时,就看看天空,无论距离有多远,我们总在同一片天空下!

20150410 递归实现八皇后问题

2015-04-10 Lover雪儿

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

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

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

 

    当年高斯先生没日没夜的计算,得出结论是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,内容如下所示:

 

posted on 2015-04-10 21:30  Lover雪儿  阅读(297)  评论(0编辑  收藏  举报