DFS典型问题
核心:回溯
注意:Queen[i] = j表示该皇后位于第i行第j列;
(凡
也是这样,看了最后输出结果才反映这个数组的用意,初始条件太重要啦!)
判断该位置是否可以放置皇后:
在当前行 line 上遍历列号;
1.判断同一列:之前放置的皇后与正准备放置的列号是否相同(列号=quenn[i] 的值)
2.判断对角线:正方形对角线斜率绝对值为 1;
int isQueen(int line) { //判断该列能否放置皇后,能放返回1,不能返回0
for (int i = 1; i < line; i++) { //检查是否在同一列上或者在同一对角线上
if (queen[i] == queen[line] || abs(queen[i] - queen[line]) == line - i) {
return 0;
}
}
return 1;
}
皇后主体:
确定当前行n,列号从 1 开始遍历,如果该位置可以放置皇后且已经放置了N个皇后,打印方案即可;否则深度+1,行变为n+1;(显然n从 1 开始取)
void Nqueen(int n,int N) {
for (int i = 1; i <= N; i++) {
queen[n] = i;
if (isQueen(n)) {
if (n == N) {
count++;
for (int i = 1; i <= N; i++) {
printf("%d ", queen[i]);
}
putchar('\n');
}
else {
Nqueen(n + 1,N);
}
}
}
}
效果:
完整代码:
#include<stdio.h>
#include<malloc.h>
#include<math.h>
int queen[100];
int count = 0;
int isQueen(int line) { //判断该列能否放置皇后,能放返回1,不能返回0
int i;
for (i = 1; i < line; i++) { //检查是否在同一列上或者在同一对角线上
if (queen[i] == queen[line] || abs(queen[i] - queen[line]) == line - i) {
return 0;
}
}
return 1;
}
void Nqueen(int n,int N) {
int i;
for (i = 1; i <= N; i++)
{
queen[n] = i;
if (isQueen(n)) {
if (n == N) {
count++;
for (int i = 1; i <= N; i++) {
printf("%d ", queen[i]);
}
putchar('\n');
}
else {
Nqueen(n + 1,N);
}
}
}
}
int main() {
Nqueen(1,5);
printf("\nall solutions = %d\n", count);
}