原题链接:迷宫问题
解题思路:
第一次写,理理思路。
1、采用广度优先搜索,先让起点入队;
2、队列首端出队,将下一步可达位置入队,并标记距离为上一步的距离 + 1;
3、当队列不为空时循环2过程,最后得到结果。
注意事项:
1、因为是广度优先遍历,各条路线的距离层层递增,最先找到终点的为最短路径,即可返回;
2、在某位置向四周查找下一可达位置时,既要判断在边界内且可通,也要判断是否为已经进行过此操作的位置,防止重复。
参考代码:
#include<stdio.h> #include<string.h> // 最大行列数 #define MAXRCS 100 // 迷宫地图结构体,sign数组列数 + 1,存放'\0' typedef struct MazeMap { char sign[MAXRCS][MAXRCS + 1]; // 标志 int step[MAXRCS][MAXRCS]; // 目前步数 } MazeMap; // 入口出口坐标 int sx, sy, ex, ey; // 上下左右移动 int xp[] = { -1, 1, 0, 0 }; int yp[] = { 0, 0, -1, 1 }; int BFSTraverse(MazeMap *map, int n, int m) { // 有多少可通点,进队元素就有多少个 int queuex[MAXRCS * MAXRCS], queuey[MAXRCS * MAXRCS]; int front = 0, rear = 0, tx, ty, nx, ny; // 将入口坐标入队 queuex[rear] = sx; queuey[rear++] = sy; map->step[sx][sy] = 1; // 与未做出尝试的坐标区别开,取1,最后再减去 // 队列不为空时循环,即还有通路 while (front != rear) { tx = queuex[front]; ty = queuey[front++]; if (tx == ex && ty == ey) { return map->step[ex][ey] - 1; } for (int i = 0; i < 4; i++) { nx = tx + xp[i]; ny = ty + yp[i]; // 向四周做出尝试 // 下一步的坐标在地图内 ------------------ 为通路 ----------------- 未在此坐标向四周做出尝试 if (nx >= 0 && ny >= 0 && nx < n && ny < m && map->sign[nx][ny] != '#' && map->step[nx][ny] == 0) { queuex[rear] = nx; queuey[rear++] = ny; // 为通路且未尝试过,进队 map->step[nx][ny] = map->step[tx][ty] + 1; // 到此处步数 + 1 (也标记了此处做出了尝试) } } } return -1; // 到此处说明无可达路径 } int main() { MazeMap map; int t, n, m; scanf("%d", &t); while (t--) { // 清空迷宫地图 memset((void *)&map, 0, sizeof(map)); // 初始化迷宫 scanf("%d%d", &n, &m); scanf("%*[^\n]"); scanf("%*c"); for (int i = 0; i < n; i++) { gets(map.sign[i]); } // 确定迷宫入口出口 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map.sign[i][j] == 'S') { sx = i; sy = j; } if (map.sign[i][j] == 'E'){ ex = i; ey = j; } } } // 广度优先遍历 int res = BFSTraverse(&map, n, m); printf("%d\n", res); } return 0; }
0.0分
15 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复