//本题是典型的搜索题,每一行有n种情况,一行行的枚举即可。
下面是我AC的代码:
#include<stdio.h>
#include<math.h>
int n, cnt, a[15], flag, times; //数组a储存每一行棋子的列数
times = 3;
void dfs(int x) { //参数x为现在到了第几行
int i, j;
if (x == n + 1) { //x == n + 1时说明n行已经枚举完了
if (times) { //判断3次输出机会是否用完
for (int i = 1; i <= n; i++)
printf("%d ", a[i]); //输出每行棋子所在的列数
printf("\n");
times--;
}
cnt++; //满足情况的次数+1
return;
}
for (j = 1; j <= n; j++) { //枚举这一行的n列
flag = 0;
for(i = 1; i < x; i++)
if (abs(a[i] - j) == abs(i - x) || a[i] == j) { //因为与对角线平行的线斜率为1或-1,那么线上两点的横、纵坐标之差的绝对值相等,后者是判断是否和上面的棋子在同一列
flag = 1; //如果这一行目前枚举的纵坐标不符题意,标记为1,跳出循环
break;
}
if (!flag) { //!flag等价于 flag == 0,即枚举的纵坐标符和题意
a[x] = j; //把这个纵坐标加入数组a中
dfs(x + 1); //继续下一行
}
}
}
int main() {
scanf("%d", &n);
dfs(1); //从第一行开始
printf("%d", cnt); //输出满足的种类数
return 0;
}