每一行放一个皇后,那么就不存在行上的限制。
只存在列上的限制,左斜线的限制和右斜线的限制。
我们可以分别用三个数来代表列上的限制,左斜线的限制和右斜线的限制。
假如在八皇后中第一行放的是
那么第二行列上的限制就是
左斜线的限制就是
右斜线的限制就是
三个限制或得到整个的限制
也就是说第二行除了这几个地方不可以放,其他都可以
其他行也是一样的处理。
public static int num2(int n) {
if(n<1 || n>32) {
return 0;
}
//-1的补码就是32个1
int limit = n == 32?-1:(1<<n)-1;
return process2(limit,0,0,0);
}
//colLimt 在列上面的限制。
//leftDiaLim在左斜线上的限制。
//rightDiaLim在右斜线上的限制。
public static int process2(int limit,
int colLim,
int leftDiaLim,
int rightDiaLim) {
if(colLim == limit) {//当列的限制已经满了的时候说明所有的行都已经放了皇后了
return 1;
}
//pos代表本行可以放皇后的所有位置
int pos = limit & (~(colLim | leftDiaLim | rightDiaLim));
int mostRightOne = 0;
int res = 0;
while(pos!=0) {
//得到最右侧的1
mostRightOne = pos & (~pos + 1);
pos = pos - mostRightOne;
res += process2(limit,
colLim | mostRightOne,//列上的限制就是前面列上的限制和当前列上的限制。
(leftDiaLim | mostRightOne) << 1,//左斜线的限制就是之前的左斜线的限制再往左边移一下,再加上当前列左边的限制
(rightDiaLim | mostRightOne) >> 1);
}
return res;
}
因为int类型只有32位,所以当超过32皇后的问题是无法解决的,更换类型可以。