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);
}
}