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 }
复制代码

 

 
posted @   海浩河  阅读(294)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示