问题分析:
1. 对于同一条对角线来说,i + j = 定值 或则 i - j = 定值!可以用于简化判断是否在同一条对角线上有重复点。
2. 固定一列用循环来遍历每一个点所具有的情况。
3. 回溯退回假定的可行点,重新递归。
#include <stdio.h>
int down[16] = {0};
int up[16] = {0};
int column[9] = {0};
int sum = 0;
void tryqueen(int i) {
int j;
for (j = 1; j <= 8; j++) {
if (column[j] || down[i - j + 7] || up[i + j - 2]) {
continue;
}
column[j] = 1;
down[i - j + 7] = 1;
up[i + j - 2] = 1;
if (i == 8) {
sum++;
} else {
tryqueen(i + 1);//递归。
}
column[j] = 0;//把皇后去掉。
down[i - j + 7] = 0;//回溯过程。
up[i + j - 2] = 0;
}
}
int main() {
tryqueen(1);
printf("%d", sum);
return 0;
}
拓展:对于n皇后问题的求解(经过检验,可行。)
#include <stdio.h>
int n;
int column[20] = {0};
int up[43] = {0};
int down[43] = {0};
int sum;
void tryqueen(int i) {
int j;
for (j = 1; j <= n; j++) {
if (column[j] || up[i + j - 2] || down[i - j + 19]) {
continue;
}
column[j] = 1;
up[i + j - 2] = 1;
down[i - j + 19] = 1;
if (i == n) {
sum++;
} else {
tryqueen(i + 1);
}
column[j] = 0;
up[i + j - 2] = 0;
down[i - j + 19] = 0;
}
}
int main() {
scanf("%d", &n);
tryqueen(1);
printf("%d\n", sum);
return 0;
}