c语言利用栈求解迷宫问题迷宫问题描述: 用户输入m行n列迷宫,O为可到达点,X为不可到达点,S为起点,E为终点,有一小虫,想从S走到E。该虫只能上,下、左,石四个方向移动,且不能出界。求从S到E的最短“可行”路线,并以文件形式输入和输出
时间: 2023-11-11 09:06:44 浏览: 103
好的,这是一个比较经典的迷宫问题,可以使用深度优先搜索或广度优先搜索来解决。这里我给出一个使用栈和广度优先搜索的解法,并且将结果保存到文件中。
首先,我们可以将迷宫抽象成一个二维数组,用0表示可以通过的路径,用1表示不可通过的路径,用2表示起点,用3表示终点。在搜索过程中,我们可以用一个二维数组记录每个点的状态,用0表示未访问过,用1表示已访问过。
具体实现可以参考以下代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义坐标点结构体
typedef struct {
int x;
int y;
} Point;
// 定义栈结构体
typedef struct {
Point data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void init_stack(Stack *s) {
s->top = -1;
}
// 判断栈是否为空
int is_empty(Stack *s) {
return s->top == -1;
}
// 判断栈是否已满
int is_full(Stack *s) {
return s->top == MAX_SIZE - 1;
}
// 入栈
void push(Stack *s, Point p) {
if (is_full(s)) {
printf("stack overflow\n");
exit(1);
}
s->data[++(s->top)] = p;
}
// 出栈
Point pop(Stack *s) {
if (is_empty(s)) {
printf("stack underflow\n");
exit(1);
}
return s->data[(s->top)--];
}
// 读取迷宫数据
void read_maze(int maze[][MAX_SIZE], int m, int n) {
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
scanf("%d", &maze[i][j]);
}
}
}
// 打印迷宫
void print_maze(int maze[][MAX_SIZE], int m, int n) {
int i, j;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%d ", maze[i][j]);
}
printf("\n");
}
}
// 判断点是否越界或已被访问
int is_valid(int maze[][MAX_SIZE], int visited[][MAX_SIZE], int x, int y) {
return x >= 0 && x < MAX_SIZE && y >= 0 && y < MAX_SIZE && maze[x][y] == 0 && visited[x][y] == 0;
}
// 搜索迷宫
void search_maze(int maze[][MAX_SIZE], int visited[][MAX_SIZE], int m, int n, Point start, Point end, FILE *fp) {
Stack s;
Point cur, next;
int found = 0;
int i, j;
// 初始化栈和visited数组
init_stack(&s);
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
visited[i][j] = 0;
}
}
// 将起点入栈
push(&s, start);
visited[start.x][start.y] = 1;
// 开始搜索
while (!is_empty(&s)) {
// 出栈
cur = pop(&s);
// 判断是否到达终点
if (cur.x == end.x && cur.y == end.y) {
found = 1;
break;
}
// 将当前点的四个邻居入栈
next = cur;
next.x--;
if (is_valid(maze, visited, next.x, next.y)) {
push(&s, next);
visited[next.x][next.y] = 1;
}
next = cur;
next.x++;
if (is_valid(maze, visited, next.x, next.y)) {
push(&s, next);
visited[next.x][next.y] = 1;
}
next = cur;
next.y--;
if (is_valid(maze, visited, next.x, next.y)) {
push(&s, next);
visited[next.x][next.y] = 1;
}
next = cur;
next.y++;
if (is_valid(maze, visited, next.x, next.y)) {
push(&s, next);
visited[next.x][next.y] = 1;
}
}
// 输出结果到文件
if (found) {
// 找到了终点
fprintf(fp, "shortest path:\n");
cur = end;
while (cur.x != start.x || cur.y != start.y) {
fprintf(fp, "(%d, %d)\n", cur.x, cur.y);
// 找到当前点的前驱点
next = cur;
next.x--;
if (next.x >= 0 && visited[next.x][next.y] > 0 && visited[next.x][next.y] < visited[cur.x][cur.y]) {
cur = next;
continue;
}
next = cur;
next.x++;
if (next.x < MAX_SIZE && visited[next.x][next.y] > 0 && visited[next.x][next.y] < visited[cur.x][cur.y]) {
cur = next;
continue;
}
next = cur;
next.y--;
if (next.y >= 0 && visited[next.x][next.y] > 0 && visited[next.x][next.y] < visited[cur.x][cur.y]) {
cur = next;
continue;
}
next = cur;
next.y++;
if (next.y < MAX_SIZE && visited[next.x][next.y] > 0 && visited[next.x][next.y] < visited[cur.x][cur.y]) {
cur = next;
continue;
}
}
fprintf(fp, "(%d, %d)\n", cur.x, cur.y);
} else {
// 没有找到终点
fprintf(fp, "no path found\n");
}
}
int main() {
int maze[MAX_SIZE][MAX_SIZE];
int visited[MAX_SIZE][MAX_SIZE];
int m, n;
Point start, end;
FILE *fp;
// 读取迷宫数据
scanf("%d%d", &m, &n);
read_maze(maze, m, n);
// 找到起点和终点
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (maze[i][j] == 2) {
start.x = i;
start.y = j;
} else if (maze[i][j] == 3) {
end.x = i;
end.y = j;
}
}
}
// 打开输出文件
fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("failed to open file\n");
exit(1);
}
// 搜索迷宫
search_maze(maze, visited, m, n, start, end, fp);
// 关闭文件
fclose(fp);
return 0;
}
```
这个程序的主要思路是:使用一个栈来保存待访问的点,每次从栈中取出一个点进行判断,如果是终点则搜索结束,否则将其四个邻居中的可行点入栈,并将其状态设置为已访问。搜索结束后,输出最短路径到文件中。
需要注意的是,由于栈的大小是固定的,如果迷宫比较大,可能会导致栈溢出。另外,本程序中没有对输入数据进行严格的检查,如果用户输入的数据不符合要求,可能会导致程序出错。
阅读全文