http://blog.163.com/soonhuisky@126/blog/static/157591739201321293910243/ 代码与注释
http://blog.csdn.net/xadillax/article/details/6512318 代码与讲解
结合代码
void init(int row, int ld, int rd)
{
int pos, p;
if ( row != upperlim )
{
pos = upperlim & (~(row | ld | rd ));
while ( pos )
{
p = pos & (~pos + 1); //取得最高位的1,即某个可放置的位置
pos = pos - p; // 剩余可放置位置
init(row | p, (ld | p) << 1, (rd | p) >> 1); // 下一轮中列,及两条斜线被占用的位置
}
}
else
{
++Ans;
}
}
自己加的一点理解笔记:
8皇后是行、列与两个对角线不能冲突。
而逐行进行放置就不需要考虑行的问题,只需逐列考虑列及对角线是否冲突即可。
依次放第一行的列,第二行的列,
直到第n行的列。
图1,先放第一行第一列,并用二进制位标记,
同时标记第二行中不可放置的位置。注:斜线
的标记不必一次标完,每次放下一行时再标记即可。
图2,准备在第二行的某列上放,由于1,2列冲突所以
放第3列,然后标记下一行哪些列被斜线占据,标记
好后并移位(这里包含上一行的当前行的斜线位标记,
移位后就是下一行不能被占用的位置,因为两个斜线
是向两侧延伸),然后就标出了下一行哪些位置不能使用。
上述的过程递归进行,即
如果还有某个位置没放,在第一行的某列放
让后放置第2行某列
...
放置第n行的某列
如果某个位置不可放置,回溯到前一步,如果全部放置完毕则记录一个答案。
最后表示斜线所需要的二进制位和列一样为n位,即表示当前行的某些列是否被斜线占用即可。