代码及解释
#include <stdio.h>
#include <stdint.h>
// 经典的 N皇后问题,以前讲剪枝的时候就刷过
//
// 人畜无害的数据范围,普通搜索也不会出问题
// 但是第一次做竟然 TLE 了……
// 然后改成位运算优化的,又 TLE了……
// 然后改成 C 语言,AC了 ?!奇葩的评测机
// l mid r三个变量分别是标记一个棋子对左下 正下和右下的影响
int search(int n, uint16_t l, uint16_t mid, uint16_t r, int depth) {
if (depth == n) {
return 1;
} else {
// 当前能不能放棋子
uint16_t p = l | mid | r;
// 逻辑非蕴含 !(p -> p + 1) <=> ((~p)&(p+!))
// 得到右边的第一个 0 位
uint16_t pos = (~p) & (p + 1);
// 当前层的可行数
int ans = 0;
// 边界是 p == 1 << n
while (pos < 1 << n) {
// 在第一个能下子的地方下子
// 向左下的斜线
uint16_t tl = (l | pos) << 1;
// 正下方的斜线
uint16_t tmid = mid | pos;
// 向右下的斜线
uint16_t tr = (r | pos) >> 1;
// dfs 下一层
ans += search(n, tl, tmid, tr, depth + 1);
// 把已经遍历过的地方标记为不可下
p = p | pos;
//继续再求第一个可下子的位置
pos = (~p) & (p + 1);
}
return ans;
}
}
int main() {
int n;
scanf("%d", &n);
while (n) {
int ans = search(n, 0, 0, 0, 0);
printf("%d\n", ans);
scanf("%d", &n);
}
return 0;
}