在一个 m×n 的迷宫里,从起点开始,依次按东(右)、南(下)、西(左)、北(上) 4 个方向探索通路,直至达到终点为止。
迷宫由字符组成,W 表示墙,. 表示空地,请编写程序,输出你找到的首条通道。
输入格式
迷宫的行数 m 和列数 n (0<m,n≤100)
m 行 n 列字符
起点的行号(0 ~ m - 1)和列号(0 ~ n - 1)
终点的行号(0 ~ m - 1)和列号(0 ~ n - 1)
输出格式
若问题无解,则输出 None
若问题有解,则输出迷宫:
W 表示墙
. 表示未走过的空地
o 表示走不通而退回时经过的空地
- 表示通道经过的空地
输入样例1
5 7
W W . W W W W
W . . . W . .
W . W W W . W
W . W . . . W
W W W . W W W
0 2
4 3
输出样例1
None
输入样例2
5 7
W W . W W W W
W . . . W . .
W . W W W . W
W . . . W . W
W W W . W W W
0 2
4 3
输出样例2
W W * W W W W
W * * o W . .
W * W W W . W
W * * * W . W
W W W * W W W
- 知识点:dfs,回溯时字符的设置。
思路:
- 本题为一道dfs,我们只需要在回溯时将字符改变即可。
- 还有就是None的输出,None的输出适合在主函数main中进行输出,我们需要设置一个变量,当找到出口时flag=1,在主函数中判断flag的值即可。
纠正:
-
边界问题,我们最好是在dfs中对room数组和book数组进行修改这样方便回溯,因此我就在传入参数的时候dfs(start_x,start-1)(我传入的参数并不是入口参数而是列-1,因为我先向右走)
-
注:边界问题不是很清楚
-
注:这个不一定是正确算法只是刚好能通过测试点
-
注:欢迎大佬指正
源码:
#include<bits/stdc++.h>
using namespace std;
int m, n;
int start_x, start_y;
int end_x, end_y;
char room[105][105];
int book[105][105];
int flag=0;
void dfs(int x, int y) {
int next[4][2] = {
{0,1},{1,0},{0,-1},{-1,0}
};
if (x == end_x && y == end_y&&flag==0) {
for (int i = 0;i < m;i++) {
for (int j = 0;j < n;j++) {
if (j != n - 1)
cout << room[i][j] << " ";
else
cout << room[i][j] << endl;
}
}
flag=1;
return;
}
int tx=x, ty=y;
for (int i = 0;i < 4;i++) {
tx = x + next[i][0];
ty = y + next[i][1];
if (tx < 0 || ty < 0 || tx >= m || ty >= n)
continue;
if (book[tx][ty] == 0 && room[tx][ty] == '.') {
book[tx][ty] = 1;
room[tx][ty] = '*';
dfs(tx, ty);
room[tx][ty] = 'o';
book[tx][ty] = 0;
}
}
}
int main() {
cin >> m >> n;
for (int i = 0;i < m;i++) {
for (int j = 0;j < n;j++)
cin >> room[i][j];
}
cin >> start_x >> start_y >> end_x >> end_y;
// book[start_x][start_y] = 1;
// room[start_x][start_y] = '*';
dfs(start_x, start_y-1);
if(flag==0)
cout<<"None"<<endl;
}