题意:n皇后问题,'.'可以摆放,'*'不可以摆放,问有多少种摆法。
题解:普通做法会超时,要用到状态压缩,每行能摆的位置标记为0,不可以的地方标记为1,然后深搜,参数有当前行数,和列、左对角线、右对角线不可以摆放的位置标记数,然后把当前行所有可以摆放的位置都递归下去,计方法数。
#include <stdio.h>
const int N = 20;
int m[N], n, res, all;
char str[N];
void dfs(int cur, int c, int l, int r) {
if (cur == n) {
res++;
return;
}
int now = ~(m[cur] | c | l | r);//取反后0为不可摆放位,1可以摆放
int last = now & -now & all;//找到最后一个1
while (last) {
dfs(cur + 1, c | last, (l | last) << 1, (r | last) >> 1);//下一行的列、左、右不可摆放位标记
now ^= last;//最后的1标记为0
last = now & -now & all;//前一个1
}
}
int main() {
int cas = 1;
while (scanf("%d", &n) && n) {
all = (1 << n) - 1;
for (int i = 0; i < n; i++) {
m[i] = 0;
scanf("%s", str);
for (int j = 0; j < n; j++)
if (str[j] == '*')
m[i] |= (1 << j);//不可以摆放位置标记1
}
res = 0;
dfs(0, 0, 0, 0);
printf("Case %d: %d\n", cas++, res);
}
return 0;
}