八皇后问题

http://blog.csdn.net/zhong317/article/details/4586131

 

8皇后之间需满足:

             1.不在同一行上

             2.不在同一列上

             3.不在同一斜线上

             4.不在同一反斜线上

 

假设前面1列的棋子放在第3行,那当前列不能放的位置就一定是3行,2行,4行。因为如果放在这三行上就分别跟前一列的棋子同在一行、同在斜线、同在反斜线上,不符合我们的要求。现在我们用cols数组来表示8个列棋子所放的行数,数组下标从0开始,其中数组下标表示列数,数组的元素值表示该列棋子所在行数,当前列为N(N>=0,N<8),即cols[N-1]=3,则有:

                          

                      cols[N] != cols[N-1](=3,表示不在同一行)

                     

                      cols[N] != cols[N-1]-1(=3-1=2,表示不在同一斜线上)

                     

                      cols[N]!=cols[N-1]+1(=3+1,表示不在同一反斜线上)

 

      这里我们注意到,如果N-2列存在的话,那么我们还要考虑当前列N不与N-2列的棋子同行,同斜线,同反斜线。把当前列N的前面的某一列设为m,则m的所有取值为{m>=0,m<N}的集合,故又可在上面式子的基础,归纳为如下:

                   

                    cols[N] != cols[m](与第m列的棋子不在同一行)

                   

                    cols[N] != cols­­[m] -(N-m)(>=0 ,与第m列的棋子不在同一斜线上)

                   

                    cols[N] != cols­­[m] + (N-m)  (<=8-1,与第m列的棋子不在同一反斜线上)          

 

public class Queen8 {
         public static int num = 0; //累计方案总数  
        public static final int MAXQUEEN = 8;//皇后个数,同时也是棋盘行列总数  
        public static int[] cols = new int[MAXQUEEN]; //定义cols数组,表示8列棋子摆放情况 ,第k列放在第cols[k]行
          
        public void  getArrangement(int n){          //n表示
         //遍历该列所有不合法的行,并用rows数组记录,不合法即rows[i]=true  
         boolean[] rows = new boolean[MAXQUEEN];  
         for(int i=0;i<n;i++){  
            rows[cols[i]]=true;  //n不能与i同行
            int d = n-i;  
            if(cols[i]-d >= 0)rows[cols[i]-d]=true;  //n不能与i在同一斜线上  
            if(cols[i]+d <= MAXQUEEN-1)rows[cols[i]+d]=true;  //n不能与i在同一反斜线上 
            
         }  
         for(int i=0;i<MAXQUEEN;i++){  
           //判断该行是否合法    
           
           //不合法则跳过这行,继续下一行
           if(rows[i])continue;  
           
           //设置当前列合法棋子所在行数  
           cols[n] = i;  
          
           //当前列不为最后一列时  
           if(n<MAXQUEEN-1){  
             getArrangement(n+1);  
           }else{  
      
            //累计方案个数  
             num++;  
             //打印棋盘信息  
             printChessBoard();  
           }   
            
         }  
           
        }  
        
        //辅助函数,用于打印
        public void printChessBoard(){  
             
           System.out.println("第"+num+"种走法");  
             
           for(int i=0;i<MAXQUEEN;i++){  
             for(int j=0;j<MAXQUEEN;j++){  
               if(i==cols[j]){  
                 System.out.print("0 ");  
               }else  
                 System.out.print("+ ");  
             }  
             System.out.println("");  
           }  
             
        }  
        public static void main(String args[]){  
          int[] i = cols;
          int j = i.length;
          Queen8 queen = new Queen8();  
          
          //打印
          queen.getArrangement(0);
          
          //统计
          System.out.println("");
          System.out.println(MAXQUEEN+"皇后问题有"+num+"种摆放方法。"); 
        }  
}

 

posted on 2017-08-28 22:00  zhangxiaoyu  阅读(126)  评论(0)    收藏  举报

导航