add
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
// 判断当前皇后放置是否合法
|
||||
int place(int x[], int j, int n) {
|
||||
if (x[j] == j )
|
||||
return 0; // 禁用:位置在棋盘左上到右下对角线上
|
||||
// 判断是否在同一列,或者是否在同一对角线上
|
||||
for (int i = 1; i < j; i++) {
|
||||
if (x[i] == x[j] || abs(j - i) == abs(x[j] - x[i]))
|
||||
return 0; // 不合法
|
||||
}
|
||||
return 1; // 合法
|
||||
}
|
||||
|
||||
// 非递归方式解 N 皇后问题
|
||||
void nQNoRec(int x[], int n) {
|
||||
int j = 1; // j 表示当前放置第 j 个皇后
|
||||
for (int i = 1; i <= n; i++)
|
||||
x[i] = 0;
|
||||
|
||||
while (j >= 1) {
|
||||
while (x[j] < n) {
|
||||
x[j] = x[j] + 1;
|
||||
if (place(x, j, n)) {
|
||||
j = j + 1;
|
||||
if (j > n) { // 到达叶子节点
|
||||
// 输出解
|
||||
for (int i = 1; i <= n; i++)
|
||||
printf("%d\t", x[i]);
|
||||
printf("\n");
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
x[j] = 0; // 回溯时,恢复当前位置的状态
|
||||
j = j - 1; // 向上回溯
|
||||
}
|
||||
}
|
||||
// 递归方式解 N 皇后问题
|
||||
void nQueenRec(int x[], int j, int n) {
|
||||
if (j > n) { // 搜索到叶子节点
|
||||
// 输出解
|
||||
for (int i = 1; i <= n; i++)
|
||||
printf("%d\t", x[i]);
|
||||
printf("\n");
|
||||
} else { // 尝试在第 j 行放置皇后
|
||||
for (int i = 1; i <= n; i++) {
|
||||
x[j] = i;
|
||||
if (place(x, j, n))
|
||||
nQueenRec(x, j + 1, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n = 6; // 皇后个数
|
||||
int x[n + 1]; // 存储每行皇后的位置
|
||||
|
||||
printf("Recursive solution:\n");
|
||||
nQueenRec(x, 1, n); // 递归方式解法
|
||||
printf("****************************\n");
|
||||
printf("Non-recursive solution:\n");
|
||||
nQNoRec(x, n); // 非递归方式解法
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MIN_DISTANCE 2
|
||||
|
||||
// 判断当前皇后放置是否合法,并且符合安全距离条件
|
||||
int place(int x[], int j) {
|
||||
for (int i = 1; i < j; i++) {
|
||||
// 检查列冲突、对角线冲突以及最小安全距离
|
||||
if (x[i] == x[j] || abs(j - i) == abs(x[j] - x[i]) ||
|
||||
abs(x[j] - x[i]) < MIN_DISTANCE || abs(j - i) < MIN_DISTANCE) {
|
||||
return 0; // 不合法
|
||||
}
|
||||
}
|
||||
return 1; // 合法
|
||||
}
|
||||
|
||||
// 非递归方式解 N 皇后问题
|
||||
void nQNoRec(int x[], int n, int *foundSolution) {
|
||||
int j = 1; // j 表示当前放置第 j 个皇后
|
||||
for (int i = 1; i <= n; i++)
|
||||
x[i] = 0;
|
||||
while (j >= 1) {
|
||||
while (x[j] < n) {
|
||||
x[j] = x[j] + 1;
|
||||
if (place(x, j)) {
|
||||
j = j + 1;
|
||||
if (j > n) { // 到达叶子节点
|
||||
*foundSolution = 1;
|
||||
return; // 找到一个解即可返回
|
||||
}
|
||||
}
|
||||
}
|
||||
x[j] = 0; // 回溯时,恢复当前位置的状态
|
||||
j = j - 1; // 向上回溯
|
||||
}
|
||||
}
|
||||
|
||||
// 递归方式解 N 皇后问题
|
||||
void nQueenRec(int x[], int j, int n, int *foundSolution) {
|
||||
if (j > n) { // 搜索到叶子节点
|
||||
*foundSolution = 1;
|
||||
return; // 找到一个解即可返回
|
||||
} else { // 尝试在第 j 行放置皇后
|
||||
for (int i = 1; i <= n; i++) {
|
||||
x[j] = i;
|
||||
if (place(x, j))
|
||||
nQueenRec(x, j + 1, n, foundSolution);
|
||||
if (*foundSolution) return; // 如果已经找到解,则提前退出
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
for (int n = 1; n <= 100; n++) {
|
||||
int x[n + 1]; // 存储每行皇后的位置
|
||||
int hasSolution = 0;
|
||||
|
||||
printf("Testing n = %d:\n", n);
|
||||
|
||||
// 使用非递归方式检查是否有解
|
||||
nQNoRec(x, n, &hasSolution);
|
||||
if (hasSolution) {
|
||||
printf("There is at least one solution for n = %d.\n", n);
|
||||
} else {
|
||||
printf("No solution found for n = %d.\n", n);
|
||||
}
|
||||
|
||||
// 也可以使用递归方式进行验证(可选)
|
||||
// hasSolution = 0;
|
||||
// nQueenRec(x, 1, n, &hasSolution);
|
||||
// if (!hasSolution) {
|
||||
// printf("No solution found for n = %d using recursive method.\n", n);
|
||||
// }
|
||||
|
||||
printf("****************************\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user