LevOJ P1793 求解迷宫问题
问题描述
有一 8×8 的迷宫图,其中 O 表示通路方块,X 表示障碍方块。假设入口位置为 (0,0),出口为右下角方块位置 (7,7)。设计一个程序求指定入口到出口的一条迷宫路径。
输入描述
8 行,每行 8 个字符表示迷宫。
输入保证至少存在一条合法路径。
输出描述
8 行,每行 8 个字符,空格表示所选路径。
样例输入
OXXXXXXX
OOOOOXXX
XOXXOOOX
XOXXOXXO
XOXXXXXX
XOXXOOOX
XOOOOXOO
XXXXXXXO
样例输出
XXXXXXX
OOOXXX
X XXOOOX
X XXOXXO
X XXXXXX
X XX X
X X
XXXXXXX
思路
首先这题的第一想法是DFS 即深度优先搜索,从(0,0)出发,每次探索4个方向,下右上左,递归调用dfs
注意:当走不通时,要将原来的方块还原为O
1 #include <iostream> 2 using namespace std; 3 char maze[8][8]; 4 void dfs(int x, int y); 5 void print() 6 { 7 for (int i = 0; i < 8; i++) 8 { 9 for (int j = 0; j < 8; j++) 10 cout << maze[i][j]; 11 cout << endl; 12 } 13 } 14 int main() 15 { 16 for (int i = 0; i < 8; i++) 17 for (int j = 0; j < 8; j++) 18 cin >> maze[i][j]; 19 dfs(0, 0); 20 } 21 int dx[4] = {1, 0, -1, 0}; 22 int dy[4] = {0, -1, 0, 1}; 23 void dfs(int x, int y) 24 { 25 if (x == 7 && y == 7) 26 { 27 maze[7][7] = ' '; 28 print(); 29 return ; 30 } 31 else 32 { 33 if (maze[x][y] == 'O' && x >= 0 && x <= 7 && y >= 0 && y <= 7) 34 { 35 // 如果x y能走 则置空 36 maze[x][y] = ' '; 37 for (int i = 0; i < 4; i++) 38 { 39 maze[x][y] = ' '; 40 int newx = x + dx[i]; 41 int newy = y + dy[i]; 42 dfs(newx, newy); 43 // 若该方向不能走 则将上一个位置复原 44 maze[x][y] = 'O'; 45 } 46 } 47 } 48 }
提交后,发现有个样例超时。(该样例设计的太好了。。)估计正好全部走一遍才走通。
网上找了很久,也没能找到能优化的地方。 所以改变算法,改用广度优先搜索BFS。
BFS搜索出的路径一定是最小路径(一开始死活想不通为什么,后面突然想通了)
BFS扫描的话,相当于一层一层展开。当达到终点时,结束扫描。相当于把每条路径摆在一起,从头开始比对,那必定是最短的那条路径先结束。
那么怎么实现呢?
由于在STL中queue不能顺序遍历,这里用一个数组作为非循环队列,front和rear分别为队头和队尾,初始时设置为-1,每个进队元素有唯一的下标。
1 #include <iostream> 2 using namespace std; 3 #define MAX 100 4 int n = 8, H[4] = {0, 1, 0, -1}, V[4] = {-1, 0, 1, 0}; 5 char Maze[8][8]; 6 struct Position 7 { 8 int x, y; //当前方块位置 9 int pre; 10 }; 11 Position qu[MAX]; 12 int front = -1, rear = -1; 13 void print(int front) 14 { 15 int i, j; 16 for (i = 0; i < n; i++) 17 for (j = 0; j < n; j++) 18 if (Maze[i][j] == '*') 19 Maze[i][j] = 'O'; 20 int k = front; 21 while (k != -1) 22 { 23 Maze[qu[k].x][qu[k].y] = ' '; 24 k = qu[k].pre; //向前找 25 } 26 for (i = 0; i < n; i++) 27 { 28 for (j = 0; j < n; j++) 29 cout << Maze[i][j]; 30 cout << endl; 31 } 32 } 33 void BFS(int x, int y) 34 { 35 Position p, p1, p2; 36 p.x = x; 37 p.y = y; 38 p.pre = -1; 39 Maze[p.x][p.y] = '*'; //改为*避免重复查找 40 rear++; 41 qu[rear] = p; 42 while (front != rear) //队不空时循环 43 { 44 front++; 45 p1 = qu[front]; //出队p1 46 if (p1.x == n - 1 && p1.y == n - 1) 47 { 48 print(front); 49 return; 50 } 51 for (int k = 0; k < 4; k++) 52 { 53 p2.x = p1.x + V[k]; 54 p2.y = p1.y + H[k]; 55 if (p2.x >= 0 && p2.y >= 0 && p2.x < n && p2.y < n && Maze[p2.x][p2.y] == 'O') 56 { 57 Maze[p2.x][p2.y] = '*'; 58 p2.pre = front; 59 rear++; 60 qu[rear] = p2; //方块p2入队 61 } 62 } 63 } 64 } 65 int main() 66 { 67 for (int i = 0; i < n; i++) 68 for (int j = 0; j < n; j++) 69 cin >> Maze[i][j]; 70 BFS(0, 0); 71 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)