2010年1月13日星期三.sgu224 k皇后问题的位运算优化

2010年1月13日星期三.sgu224 k皇后问题的位运算优化

2010年1月13日星期三.sgu224
k皇后问题的位运算优化
这个是基本上学过编程的人都会写过的程序。
但是对于这个NP问题,只能搜索解决。如果写的不好的话很容易超时。
今天在Matrix67的文章中看到了使用位运算的方法,本来我还想用dancing links来
搜一下呢,这个方法太精妙了!
传送门: http://www.matrix67.com/blog/archives/266

我们知道(x&-x)是求x的最低位1,而这个操作是非常快的。
在这个递推过程中,只保存当前行的不可行解,然后利用求反和上边说的求最低位1的方法对当前
行的可行解进行遍历,然后递推求解

不过这个不是n皇后问题,是k皇后,所以还需要对算法进行一些小小的改动。
//http://www.cppblog.com/schindlerlee/
typedef 
long   long  LL;
const   int  N  =   16 ;
int  n, k;

#define  bin(x) (1 << (x))
#define  L(x) ((x) << 1)
#define  R(x) ((x) >> 1)
#define  low(x) ((x) & -(x))

int  res  =   0 , full;
// row代表列的状态,ld代表左对角线,rd代表右对角线,cnt是已经使用的皇后数
// line是已经推到了第几第几行
void  dfs( int  row,  int  ld,  int  rd,  int  cnt,  int  line)
{
  
int  p, t;
  
if  (line  <  n  &&  cnt  <  k) {
      t 
=  full  &   ~ (row  |  ld  |  rd);
      
while  (t  !=   0 ) {
          p 
=  low(t);
          t 
^=  p;
          dfs(row 
+  p, L(ld  +  p), R(rd  +  p), cnt  +   1 , line  +   1 );     // 下一行
      }
      dfs(row, L(ld), R(rd), cnt, line 
+   1 );     // 此行空
  }  else   if (cnt  ==  k){
      res
++ ;
  }

}

int  main()
{
  
int  i, j;
  scanf(
" %d%d " & n,  & k);
  full 
=  bin(n)  -   1 ;
  dfs(
0 0 0 0 0 );
  printf(
" %d\n " , res);
  
return   0 ;
}



你可能感兴趣的:(2010年1月13日星期三.sgu224 k皇后问题的位运算优化)