题解 | #迷宫问题#
迷宫问题
https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc
#include <iostream>
#include <vector>
using namespace std;
//判断是否是单一方向通路。如果是,则返回相应方向d(down),r(right),u(up),l(left);如果不是,返回f(false)
char singledirection(pair<int, int>pos, vector<vector<int>> maze) {
if (pos.first + 1 <= maze.size() - 1 &&
maze[pos.first + 1][pos.second] == 0
&& !(pos.second + 1 <= maze[0].size() - 1 &&
maze[pos.first][pos.second + 1] == 0)
&& !(pos.first - 1 >= 0 &&
maze[pos.first - 1][pos.second] == 0)
&& !(pos.second - 1 >= 0 &&
maze[pos.first][pos.second - 1] == 0)) {
return 'd';
}
if (pos.second + 1 <= maze[0].size() - 1 &&
maze[pos.first][pos.second + 1] == 0
&& !(pos.first + 1 <= maze.size() - 1 &&
maze[pos.first + 1][pos.second] == 0)
&& !(pos.first - 1 >= 0 &&
maze[pos.first - 1][pos.second] == 0)
&& !(pos.second - 1 >= 0 &&
maze[pos.first][pos.second - 1] == 0)) {
return 'r';
}
if (pos.first - 1 >= 0 &&
maze[pos.first - 1][pos.second] == 0
&& !(pos.first + 1 <= maze.size() - 1 &&
maze[pos.first + 1][pos.second] == 0)
&& !(pos.second + 1 <= maze[0].size() - 1 &&
maze[pos.first][pos.second + 1] == 0)
&& !(pos.second - 1 >= 0 &&
maze[pos.first][pos.second - 1] == 0)) {
return 'u';
}
if (pos.second - 1 >= 0 &&
maze[pos.first][pos.second - 1] == 0
&& !(pos.first + 1 <= maze.size() - 1 &&
maze[pos.first + 1][pos.second] == 0)
&& !(pos.second + 1 <= maze[0].size() - 1 &&
maze[pos.first][pos.second + 1] == 0)
&& !(pos.first - 1 >= 0 &&
maze[pos.first - 1][pos.second] == 0)) {
return 'l';
}
return 'f';
}
void solution(pair<int, int>pos, vector<vector<int>> maze,
vector<pair<int, int>> route, vector<vector<pair<int, int>>>& routes) {
//如果是单一方向且当前位置pos(position)不是终点,1.将当前位置记录至路径route 2.当前位置地图maze值设为1(不可通过)3.pos向相应方向移动
while (singledirection(pos, maze) != 'f' && !(pos.first == maze.size() - 1 &&
pos.second == maze[0].size() - 1)) {
char direction = singledirection(pos, maze);
if (direction == 'd') {
route.push_back(pos);
maze[pos.first][pos.second] = 1;
pos.first++;
} else if (direction == 'r') {
route.push_back(pos);
maze[pos.first][pos.second] = 1;
pos.second++;
} else if (direction == 'u') {
route.push_back(pos);
maze[pos.first][pos.second] = 1;
pos.first--;
} else if (direction == 'l') {
route.push_back(pos);
maze[pos.first][pos.second] = 1;
pos.second--;
}
}
//当前位置pos为终点,将pos记录进route,并将route记录进routes
if (pos.first == maze.size() - 1 && pos.second == maze[0].size() - 1) {
route.push_back(pos);
routes.push_back(route);
}
//当前位置pos有多个方向通路,按下、右,上,左顺序处理
if (pos.first + 1 <= maze.size() - 1 &&
maze[pos.first + 1][pos.second] == 0) {
vector<pair<int, int>> route_copy(route);
vector<vector<int>> maze_copy(maze);
pair<int, int>pos_copy = pos;
route_copy.push_back(pos);
maze_copy[pos.first][pos.second] = 1;
pos_copy.first++;
solution(pos_copy, maze_copy, route_copy, routes);
maze[pos.first + 1][pos.second] = 1;
solution(pos, maze, route, routes);
}
if (pos.second + 1 <= maze[0].size() - 1 &&
maze[pos.first][pos.second + 1] == 0) {
vector<pair<int, int>> route_copy(route);
vector<vector<int>> maze_copy(maze);
pair<int, int>pos_copy = pos;
route_copy.push_back(pos);
maze_copy[pos.first][pos.second] = 1;
pos_copy.second++;
solution(pos_copy, maze_copy, route_copy, routes);
maze[pos.first][pos.second + 1] = 1;
solution(pos, maze, route, routes);
}
if (pos.first - 1 >= 0 &&
maze[pos.first - 1][pos.second] == 0) {
vector<pair<int, int>> route_copy(route);
vector<vector<int>> maze_copy(maze);
pair<int, int>pos_copy = pos;
route_copy.push_back(pos);
maze_copy[pos.first][pos.second] = 1;
pos_copy.first--;
solution(pos_copy, maze_copy, route_copy, routes);
maze[pos.first - 1][pos.second] = 1;
solution(pos, maze, route, routes);
}
if (pos.second - 1 >= 0 &&
maze[pos.first][pos.second - 1] == 0) {
vector<pair<int, int>> route_copy(route);
vector<vector<int>> maze_copy(maze);
pair<int, int>pos_copy = pos;
route_copy.push_back(pos);
maze_copy[pos.first][pos.second] = 1;
pos_copy.second--;
solution(pos_copy, maze_copy, route_copy, routes);
maze[pos.first][pos.second - 1] = 1;
solution(pos, maze, route, routes);
}
}
int main() {
int m, n;
while (cin >> m >> n) { // 注意 while 处理多个 case
vector<vector<int>> maze(m, vector<int>(n));
for (auto& i : maze) {
for (auto& j : i) {
cin >> j;
}
}
pair<int, int> pos(0, 0);
vector<vector<pair<int, int>>> routes;
vector<pair<int, int>> route;
solution(pos, maze, route, routes);
int min = 0;
for (int i = 1; i < routes.size(); i++) {
if (routes[min].size() > routes[i].size()) {
min = i;
}
}
for (auto& i : routes[min]) {
cout << '(' << i.first << ',' << i.second << ')' << endl;
}
}
}
// 64 位输出请用 printf("%lld")
此题可使用递归的方式解决。
设置变量:
pos当前位置,maze迷宫地图,route已走过的路径,routes到达终点的路径的集合
设置方法singledirection判断当前位置是否只有一个方向的通路。如果是,返回方向。
设置方法solution(pos,maze,route,routes)
pos可分为三种情况
- pos到达终点
- pos未到达终点,pos只有一个方向的通路
- pos未到达终点,pos有多个方向通路
分别处理
- pos到达终点
将pos记录进route,并将route记录进routes
- pos未到达终点,pos只有一个方向的通路
循环执行:1.将当前位置记录至路径route 2.当前位置地图maze值设为1(不可通过)3.pos向相应方向移动
- pos未到达终点,pos有多个方向通路(按下、右,上,左顺序处理)
设置route_copy,maze_copy,pos_copy。
1.maze_cope(pos)设为1(不可通过)
2.pos_cope=pos+1(pos向相应方向移动)
3.pos记录进route_copy
4.调用solution(pos_copy, maze_copy, route_copy, routes)
5.maze(pos_copy)= 1;
6.调用solution(pos, maze, route, routes)