在n*n的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。共有多少中放法?
1.回溯法
#include <stdio.h>
#include <stdlib.h>
int *x;
int n;
int sum;
int place(int k)
{
for (int i = 1; i < k; i++) {
if (x[i] == x[k] || abs(x[i] - x[k]) == abs(i - k)) {
return 0;
}
}
return 1;
}
void backtrack(int t)
{
if (t > n) sum++;
else
{
for (int i = 1; i <= n; i++) {
x[t] = i;
if (place(t)) {
backtrack(t+1);
}
}
}
}
int main()
{
printf("请输入n的值:\n");
scanf("%d", &n);
int a[n+1];
x = a;
sum = 0;
backtrack(1);
printf("当n = %d时,共有%d种不同的放置方法.", n, sum);
return 0;
}
2. 暴力求解
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, const char * argv[])
{
int num, n;
int count = 0;
int *x;
printf("请输入n的值:\n");
scanf("%d", &n);
int a[n+1];
x = a;
for (num = 0; num < pow(n, n); num++) {
int j = num;
for (int i = 0; i < n; i++) {
x[i] = j % n;
j = j / n;
}
int k = 1;
for (int i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (a[i] == a[j] || abs(i - j) == abs(a[i] - a[j])) {
k = 0;
}
}
}
if (k) {
count++;
}
}
printf("当n = %d时,共有%d中不同的放置方法.\n", n, count);
return 0;
}