经典八皇后问题:
在8×8的国际象棋棋盘上摆放8个皇后,但是皇后之间不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
由规则可知,8个皇后一定是放置在不同的行。可以尝试从第一行开始选择1列放置一个皇后,然后再第二行,但是第二行选择放置皇后不能与之前冲突,直到第八个皇后放置好之后得到一种放置方法。
通过深度搜索的方法,计算出所有的解决方法。
问题的关键是如何判断放置的皇后与之前的冲突:
用col, ld, rd三个int型变量的最后8位表示每一行的冲突情况;
上图为6皇后问题的示例:
第4行放置前:col = 101010, ld = 100100,rd = 000111,只有当所有col, ld, rd的同一位都为0,才能放置皇后。
第4行放置后:col = 111010, ld = 110100, rd = 010111,两条对角线对下一行的影响分别是,ld << 1, rd >>1。
第5行放置前:col = 111010, ld = 101000, rd = 001011。
链接:HDU N皇后
#include <stdio.h>
#define N 10
int cnt;
void dfs(int cur, int n, int col, int ld, int rd) {
if(cur == n)
cnt++;
else {
int t = 1;
int mask = col | ld | rd;
for(int i = 0; i < n; i++) {
t = 1 << i;
if(~mask & t) {
dfs(cur+1, n, col|t, (ld|t)<<1, (rd|t)>>1);
}
}
}
}
int main() {
int n, num[N];
for(int i = 0; i < N; i++) {
cnt = 0;
dfs(0, i+1, 0, 0, 0);
num[i] = cnt;
}
while(scanf("%d", &n) != EOF) {
if(n == 0)
break;
printf("%d\n", num[n-1]);
}
return 0;
}