用c语言实现八数码算法并且加上注释
时间: 2023-11-10 13:10:01 浏览: 81
以下是用C语言实现八数码算法的代码,并加上了注释以便理解:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 9 // 八数码问题中数字最多只有9个
int n; // 数字个数
int puzzle[MAXN][MAXN]; // 数字矩阵
int step[MAXN]; // 存储从初始状态到当前状态的路径
int path[MAXN]; // 存储路径
int dx[4] = {0, 1, 0, -1}; // x方向的偏移量
int dy[4] = {1, 0, -1, 0}; // y方向的偏移量
int h() { // 计算曼哈顿距离
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (puzzle[i][j]) // 如果不是空格
ans += abs(i - (puzzle[i][j] - 1) / n) + abs(j - (puzzle[i][j] - 1) % n);
return ans;
}
int dfs(int depth, int maxDepth, int last) { // 深度优先搜索
if (depth + h() > maxDepth) return 0; // 剪枝,如果当前深度加上曼哈顿距离大于最大深度,返回0
if (!h()) return 1; // 如果曼哈顿距离为0,说明已经达到目标状态,返回1
int x, y, tx, ty;
for (int i = 0; i < n * n; i++) // 枚举所有数字
if (puzzle[i / n][i % n] == 0) { // 如果当前位置是空格
x = i / n; // 空格的横坐标
y = i % n; // 空格的纵坐标
break;
}
for (int i = 0; i < 4; i++) { // 枚举四个方向
tx = x + dx[i]; // 计算新的横坐标
ty = y + dy[i]; // 计算新的纵坐标
if (tx < 0 || ty < 0 || tx >= n || ty >= n || depth + h() > last) continue; // 如果超出边界或者当前深度加上曼哈顿距离大于最大深度,跳过
puzzle[x][y] = puzzle[tx][ty]; // 交换数字
puzzle[tx][ty] = 0; // 空格移到新位置
step[depth] = i; // 记录移动方向
if (dfs(depth + 1, maxDepth, last)) return 1; // 递归搜索
puzzle[tx][ty] = puzzle[x][y]; // 恢复数字
puzzle[x][y] = 0; // 恢复空格
}
return 0;
}
int ida_star() { // 迭代加深搜索
int maxDepth = h(), last;
while (1) { // 不断增加最大深度
memset(step, 0, sizeof(step)); // 初始化step数组
if (dfs(0, maxDepth, last)) return maxDepth; // 如果找到解,返回最大深度
last = maxDepth; // 更新最大深度
maxDepth = 1e9; // 将最大深度设为一个很大的数
}
}
int main() {
scanf("%d", &n); // 输入数字个数
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &puzzle[i][j]); // 输入数字矩阵
int depth = ida_star(); // 求解
if (depth == 0) printf("No solution.\n"); // 如果没有解,输出No solution.
else {
int cnt = 0;
for (int i = depth - 1; i >= 0; i--)
path[cnt++] = step[i]; // 将路径倒序存储到path数组中
for (int i = cnt - 1; i >= 0; i--) {
if (path[i] == 0) printf("r"); // 右移
else if (path[i] == 1) printf("d"); // 下移
else if (path[i] == 2) printf("l"); // 左移
else if (path[i] == 3) printf("u"); // 上移
}
printf("\n"); // 输出换行符
}
return 0;
}
```
注:以上代码实现的是IDA*算法求解八数码问题,不是A*算法。
阅读全文