现在有一个迷宫,在里面随机设有不同位置的宝藏,请使用C语言编程实现寻找一条最短路径,要求途径宝藏位置并走出迷宫,最后输出路径左转和右转的信息。
时间: 2023-11-09 22:05:32 浏览: 84
用C语言编程实现最短路径.doc
好的,这是一个比较常见的迷宫求解问题,可以使用广度优先搜索算法(BFS)来解决。下面是一个简单的 C 语言实现示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 10
#define COLS 10
// 迷宫地图,0 表示可走,1 表示障碍
int maze[ROWS][COLS] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 0, 1, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{1, 1, 1, 1, 0, 1, 1, 0, 1, 1},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 0}
};
// 宝藏位置数组
int treasures[3][2] = {{1, 8}, {4, 3}, {7, 8}};
// 存储每个位置的状态信息
typedef struct Node {
int x; // x 坐标
int y; // y 坐标
int steps; // 到达此位置的步数
int pre_x; // 前一个位置的 x 坐标
int pre_y; // 前一个位置的 y 坐标
char dir; // 转向信息,'L' 表示左转,'R' 表示右转
} Node;
// 队列结构体
typedef struct Queue {
int front;
int rear;
Node data[ROWS * COLS];
} Queue;
// 初始化队列
void initQueue(Queue *q) {
q->front = q->rear = 0;
}
// 判断队列是否为空
int isEmpty(Queue *q) {
return q->front == q->rear;
}
// 入队
void enQueue(Queue *q, Node n) {
q->data[q->rear++] = n;
}
// 出队
Node deQueue(Queue *q) {
return q->data[q->front++];
}
// 判断坐标是否越界或者有障碍物
int isOk(int x, int y) {
if (x < 0 || x >= ROWS || y < 0 || y >= COLS || maze[x][y] == 1) {
return 0;
}
return 1;
}
// BFS 寻找最短路径
void bfs(int sx, int sy, int ex, int ey) {
Queue q;
initQueue(&q);
Node start = {sx, sy, 0, -1, -1, 'N'};
enQueue(&q, start);
maze[sx][sy] = 1; // 标记起点已经访问过
while (!isEmpty(&q)) {
Node cur = deQueue(&q);
// 到达终点,返回路径
if (cur.x == ex && cur.y == ey) {
printf("到达终点,共走 %d 步\n", cur.steps);
int cnt = 0; // 宝藏计数器
while (cur.pre_x != -1 && cur.pre_y != -1) {
for (int i = 0; i < 3; i++) {
if (cur.x == treasures[i][0] && cur.y == treasures[i][1]) {
printf("第 %d 个宝藏在 (%d,%d),转向信息为:%c\n", ++cnt, cur.x, cur.y, cur.dir);
break;
}
}
cur = (Node){cur.pre_x, cur.pre_y, 0, 0, 0, cur.dir};
}
return;
}
// 向四个方向扩展
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
for (int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if (isOk(nx, ny)) {
Node next = {nx, ny, cur.steps + 1, cur.x, cur.y, 'N'};
if (cur.pre_x != -1 && cur.pre_y != -1) {
// 计算转向信息
if (dx[i] == cur.x - cur.pre_x && dy[i] == cur.y - cur.pre_y) {
next.dir = 'S';
} else if (dx[i] == cur.pre_x - cur.x && dy[i] == cur.pre_y - cur.y) {
next.dir = 'B';
} else if (dx[i] == 0 && dy[i] == 1) {
if (cur.x - cur.pre_x == 1) {
next.dir = 'L';
} else {
next.dir = 'R';
}
} else if (dx[i] == 0 && dy[i] == -1) {
if (cur.x - cur.pre_x == 1) {
next.dir = 'R';
} else {
next.dir = 'L';
}
} else if (dx[i] == 1 && dy[i] == 0) {
if (cur.y - cur.pre_y == 1) {
next.dir = 'R';
} else {
next.dir = 'L';
}
} else if (dx[i] == -1 && dy[i] == 0) {
if (cur.y - cur.pre_y == 1) {
next.dir = 'L';
} else {
next.dir = 'R';
}
}
}
enQueue(&q, next);
maze[nx][ny] = 1; // 标记已经访问过
}
}
}
printf("无法到达终点!\n");
}
int main() {
bfs(0, 0, 9, 9); // 起点为 (0,0),终点为 (9,9)
return 0;
}
```
这段代码中,我们首先定义了一个 10x10 的迷宫地图,其中 0 表示可以通过的路,1 表示障碍物。我们还定义了一个三个宝藏的位置数组 `treasures`,用于在找到宝藏时输出转向信息。
然后我们定义了一个 `Node` 结构体,用于存储每个位置的状态信息,包括坐标、到达此位置的步数、前一个位置的坐标和转向信息。我们还定义了一个 `Queue` 结构体作为队列,用于实现 BFS 算法。
在 `bfs` 函数中,我们首先将起点入队,并标记起点已经访问过,然后进入循环,不断出队并向四个方向扩展,直到找到终点或者队列为空。如果找到了终点,我们就可以通过回溯找到最短路径,同时输出转向信息。如果无法到达终点,我们就输出一个提示信息。
在扩展一个新的位置时,我们需要注意计算转向信息。具体来说,我们需要根据当前位置和前一个位置以及扩展方向的关系来判断左转和右转。其中,'S' 表示直行,'B' 表示掉头,'L' 表示左转,'R' 表示右转。
需要注意的是,这段代码中使用的是固定的迷宫地图和宝藏位置,实际应用中需要动态生成迷宫或者从外部读取迷宫和宝藏位置。
阅读全文