八皇后问题

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。[英国某著名计算机图形图像公司面试题]

算法1:典型的回朔算法。打印出8皇后的最终排列。
解析:递归实现n皇后问题。
算法分析:
数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第7列。如果某列上已经有皇后,则为1,否则为0。
数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14]。如果某条主对角线上已经有皇后,则为1,否则为0。
数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14]。如果某条从对角线上已经有皇后,则为1,否则为0。

 
package  org.luyang.csdn;

public   class  EightQueue {
    String[][] rec 
=   new  String[ 8 ][ 8 ];

    
int [] a  =   new   int [ 8 ];

    
int [] b  =   new   int [ 15 ];

    
int [] c  =   new   int [ 15 ];

    
int  sum;

    
public  EightQueue() {
        
super ();
        
for  ( int  i  =   0 ; i  <   this .rec.length; i ++ ) {
            
for  ( int  j  =   0 ; j  <   this .rec[i].length; j ++ ) {
                
this .rec[i][j]  =   " " ;
            }
        }

    }

    
public   void  prt() {
        System.out.println(
"" );
        
for  ( int  i  =   0 ; i  <   this .rec.length; i ++ ) {
            
for  ( int  j  =   0 ; j  <   this .rec[i].length; j ++ ) {
                System.out.print(
this .rec[i][j]  +   "   " );
            }
            System.out.println(
"" );
        }

        System.out.println(
"" );
    }

    
/**
     * set the queen of line i
     * 
     * 
@param  i
     
*/
    
void  qu( int  i) {
        
for  ( int  iColumn  =   0 ; iColumn  <   8 ; iColumn ++ ) {
            
if  (a[iColumn]  ==   0   &&  b[i  -  iColumn  +   7 ==   0
                    
&&  c[i  +  iColumn]  ==   0 ) {
                
//  do not conflict
                rec[i][iColumn]  =   " " ;
                a[iColumn] 
=   1 ;
                b[i 
-  iColumn  +   7 =   1 ;
                c[i 
+  iColumn]  =   1 ;
                
if  (i  <   7 )
                    qu(i 
+   1 );
                
else  {
                    
//  sysout
                    prt();
                    sum
++ ;
                }
                
//  whatever how to put the queen, mission is impossible. rollback
                rec[i][iColumn]  =   " " ;
                a[iColumn] 
=   0 ;
                b[i 
-  iColumn  +   7 =   0 ;
                c[i 
+  iColumn]  =   0 ;
            }
        }
    }

    
/**
     * 8 queen
     * 
@param  args
     
*/
    
public   static   void  main(String[] args) {
        EightQueue eq 
=   new  EightQueue();
        eq.qu(
0 );
        System.out.println(eq.sum);
    }
}
算法2,也不知道是从哪里剽窃过来的了,该算法没有最终答应出排列组合,仅仅给出有多少种组合,但是算法确实十分奥妙,提供出来大家分享。
package  org.luyang.csdn;

public   class  Queen {
    
static   int  sum  =   0 , upperlim  =   1 ;

    
private   static   void  test( int  row,  int  ld,  int  rd) {

        
if  (row  !=  upperlim) {
            
int  pos  =  upperlim  &   ~ (row  |  ld  |  rd);
            
while  (pos  !=   0 ) {
                
int  p  =  pos  &   - pos;
                pos 
-=  p;
                test(row 
+  p, (ld  +  p)  <<   1 , (rd  +  p)  >>   1 );
            }
        } 
else
            sum
++ ;
    }

    
public   static   void  main(String[] args) {
        
int  n  =   8 ;

        
if  (args.length  ==   1 )
            n 
=  Integer.parseInt(args[ 0 ]);

        
long  tm  =  System.currentTimeMillis();
        
if  ((n  <   1 ||  (n  >   32 )) {
            System.out.println(
"  heh..I can't calculate that. " );
            System.exit(
- 1 );
        }
        System.out.println(n 
+   "  Queens " );
        upperlim 
=  (upperlim  <<  n)  -   1 ;

        test(
0 0 0 );
        System.out.println(
" Number of solutions is  "   +  sum  +   " "
                
+  (System.currentTimeMillis()  -  tm)  +   "  milliseconds " );
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值