add
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
// 归并函数
|
||||
void merge(int arr[], int left, int middle,
|
||||
int right, int temp[]) {
|
||||
int i = left; // 左数组起始索引
|
||||
int j = middle + 1; // 右数组起始索引
|
||||
int k = left; // 合并后数组起始索引
|
||||
// 将数据复制到临时数组
|
||||
for (int m = left; m <= right; ++m)
|
||||
temp[m] = arr[m];
|
||||
// 合并临时数组到 arr[left..right]
|
||||
while (i <= middle && j <= right) {
|
||||
if (temp[i] <= temp[j])
|
||||
arr[k++] = temp[i++];
|
||||
else
|
||||
arr[k++] = temp[j++];
|
||||
}
|
||||
// 拷贝剩余元素(如果有)
|
||||
while (i <= middle)
|
||||
arr[k++] = temp[i++];
|
||||
}
|
||||
// 归并排序函数
|
||||
void mergeSort(int arr[], int left, int right, int temp[]) {
|
||||
if (left < right) {
|
||||
int middle = left + (right - left) / 2;
|
||||
mergeSort(arr, left, middle, temp); // 排左半部分
|
||||
mergeSort(arr, middle + 1, right, temp); // 排右半部分
|
||||
merge(arr, left, middle, right, temp); // 合并两个已排部分
|
||||
}
|
||||
}
|
||||
// 打印数组
|
||||
void printArray(int arr[], int size) {
|
||||
for (int i = 0; i < size; i++)
|
||||
printf("%d ", arr[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int arr[] = {8, 7, 6, 15, 4, 3, 2, 10};
|
||||
int arrSize = sizeof(arr) / sizeof(arr[0]);
|
||||
int temp[arrSize];
|
||||
printf("原始数组: ");
|
||||
printArray(arr, arrSize);
|
||||
mergeSort(arr, 0, arrSize - 1, temp);
|
||||
printf("排序后的数组: ");
|
||||
printArray(arr, arrSize);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -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.
@@ -0,0 +1,60 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NUM_PLACES 4
|
||||
|
||||
void printPath(int *path) {
|
||||
for (int i = 0; i < NUM_PLACES; ++i)
|
||||
printf("%c", 'A' + path[i]); // 将数字转换为对应的字母(例如:0 -> 'A', 1 -> 'B' 等)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 回溯函数:尝试构建所有可能的路径组合
|
||||
void backtrack(int *path, bool used[NUM_PLACES], int step) {
|
||||
// 如果已经到达了最后一个步骤,则打印路径
|
||||
if (step == NUM_PLACES) {
|
||||
printPath(path); // 调用打印函数
|
||||
return;
|
||||
}
|
||||
// 尝试每一个可能的下一个位置
|
||||
for (int next = 0; next < NUM_PLACES; ++next) {
|
||||
// 如果这个位置还没有被使用过
|
||||
if (!used[next]) {
|
||||
// 特殊情况处理:如果当前要放置的是 A (即 next == 0)
|
||||
// 并且后面还有空间放置 B (即 step + 1 < NUM_PLACES)
|
||||
// 同时 B 还没有被使用过 (!used[1])
|
||||
if (next == 0 && step + 1 < NUM_PLACES && !used[1]) {
|
||||
// 把 A 和 B 作为一对连续的位置放置
|
||||
path[step] = 0; // 放置 A
|
||||
path[step + 1] = 1; // 放置 B
|
||||
used[0] = used[1] = true; // 标记 A 和 B 已经被使用
|
||||
|
||||
// 继续递归寻找后续的路径
|
||||
backtrack(path, used, step + 2);
|
||||
|
||||
// 回溯:取消标记 A 和 B 的使用状态
|
||||
used[0] = used[1] = false;
|
||||
} else if (next != 0 && next != 1) { // 如果不是 A 或 B
|
||||
// 只放置 C 或者 D,确保 A 总是紧跟着 B 出现
|
||||
path[step] = next; // 放置 C 或 D
|
||||
used[next] = true; // 标记当前位置已被使用
|
||||
|
||||
// 继续递归寻找后续的路径
|
||||
backtrack(path, used, step + 1);
|
||||
|
||||
// 回溯:取消标记当前位置的使用状态
|
||||
used[next] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int path[NUM_PLACES]; // 创建一个用来存储路径的数组
|
||||
bool used[NUM_PLACES] = {false}; // 创建一个布尔数组来追踪哪些位置已经被使用
|
||||
|
||||
// 开始回溯,从一个空路径开始
|
||||
backtrack(path, used, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#define NUM_PLACES 4
|
||||
// 回溯函数:尝试构建所有可能的路径组合,A 总是紧跟 B
|
||||
void backtrack(int *path, bool used[NUM_PLACES], int step)
|
||||
{
|
||||
if (step >= NUM_PLACES)
|
||||
{ // 边界条件:当步骤数等于地点数时打印路径
|
||||
for (int i = 0; i < NUM_PLACES; ++i)
|
||||
printf("%c", 'A' + path[i]);
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
// 如果还有足够的空间,尝试放置 A 和 B 作为一对
|
||||
if (step + 1 < NUM_PLACES && !used[0] && !used[1]) {
|
||||
path[step] = 0; // 放置 A
|
||||
path[step + 1] = 1; // 放置 B
|
||||
used[0] = used[1] = true;
|
||||
backtrack(path, used, step + 2);
|
||||
used[0] = used[1] = false;
|
||||
}
|
||||
// 尝试放置 C 或 D
|
||||
for (int i = 2; i < NUM_PLACES; ++i) {
|
||||
if (!used[i]) {
|
||||
path[step] = i;
|
||||
used[i] = true;
|
||||
backtrack(path, used, step + 1);
|
||||
used[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
int path[NUM_PLACES];
|
||||
bool used[NUM_PLACES] = {false};
|
||||
// 开始回溯,从一个空路径开始
|
||||
backtrack(path, used, 0);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NUM_PLACES 4
|
||||
|
||||
// 函数:打印路径,将索引转换为1到4的数字表示
|
||||
void printPath(int *path) {
|
||||
for (int i = 0; i < NUM_PLACES; ++i) {
|
||||
printf("%d ", path[i] + 1); // 将索引转换为1-based索引(即0变为1, 1变为2等)
|
||||
}
|
||||
printf("\n"); // 打印完路径后换行
|
||||
}
|
||||
|
||||
// 回溯函数:生成所有符合条件的路径
|
||||
void backtrack(int *path, bool used[NUM_PLACES], int step) {
|
||||
if (step == NUM_PLACES) { // 如果已经选择了所有的地点
|
||||
printPath(path); // 打印当前路径
|
||||
return;
|
||||
}
|
||||
for (int next = 0; next < NUM_PLACES; ++next) { // 尝试选择下一个地点
|
||||
if (!used[next]) { // 如果该地点还没有被访问过
|
||||
if (next == 0 && step + 1 < NUM_PLACES && !used[1]) {
|
||||
// 如果当前要放置的是地点1,并且后面还有空间且地点2未被使用,
|
||||
// 则将地点1和地点2作为一个单元放置在一起
|
||||
path[step] = 0; // 放置地点1
|
||||
path[step + 1] = 1; // 紧接着放置地点2
|
||||
used[0] = used[1] = true; // 标记地点1和地点2为已使用
|
||||
backtrack(path, used, step + 2); // 递归尝试下一步
|
||||
used[0] = used[1] = false; // 回溯,恢复状态
|
||||
} else if (next != 0 && next != 1) {
|
||||
// 如果当前不是选择地点1或地点2,则可以选择地点3或地点4
|
||||
path[step] = next; // 放置地点3或地点4
|
||||
used[next] = true; // 标记该地点为已使用
|
||||
backtrack(path, used, step + 1); // 递归尝试下一步
|
||||
used[next] = false; // 回溯,恢复状态
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int path[NUM_PLACES]; // 用于存储路径的数组
|
||||
bool used[NUM_PLACES] = {false}; // 用于跟踪哪些地点已经被访问过
|
||||
// 从一个空路径开始回溯
|
||||
backtrack(path, used, 0);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user