package Test;

public class Test67 {

static int count = 0;

static int n ;

static int ds ;

/* n皇后位运算,出于本人的总结

  • 比如:6皇后

  • 调用nqueen row=0,ld=0,rd=0

  • ds初始化为111111(二进制)

  • row!=111111

  • row ld rd 或运算,算出最高值,取反,并且与ds(一共多少个皇后 )与运算

  • 算出的结果,1即为可以存放皇后的位置

  • (↑ps:这样做的结果就是从最低位数起取n个数为有效位置)

  • 如果pos 为0,则全部行都有满足条件的皇后,就退出,否则进入如下循环↓

  • 定义变量p存放之前运算出来的pos中最右边的1的位置

  • 然后将pos值更改,删除pos中的第p个位置的值

  • (相当于,在pos最右边的1(变量p)放置了一个皇后,所以要在pos对应位置置空,防止while循环无法退出)

  • 最后更新row,ld,rd的值

  • row为row|p,即 p每次都在每行的合理位置放置皇后,所以row|p代表棋盘中的每一行是否都有棋子

  • such as:6皇后 0 | 000001 row=000001 -> 000001 | 000100 row=000101

* ld为(ld|p)<<1 ,即 代表某个放置皇后的点的左对角线(从右上往下递增的点)在n棋盘中的占位 * ld|p表示(如:第一行)放置皇后的点(二进制数)的左对角线的占位, * <<1 : (如:第一行)的放置皇后的点(二进制数)的左对角线的占位(ld|p)。在第二行的占位,由于对角线是斜线,所以<<1 * */ static void nqueen(int row,int ld,int rd){ if(row != ds){ int pos = ds & (~(row|ld|rd)); while(pos!=0){ int p = pos & (~pos+1); pos = pos – p; nqueen(row|p,(ld|p)<<1,(rd|p)>>1);

}

}else{

count++;

}

}

public static void main(String[] args) {

n = 8;

ds = (1<<n) – 1;

System.out.println(ds);

nqueen(0,0,0);

System.out.println(count);

}

}