这类迷宫路径回溯问题, 可以利用两遍 bfs() 来解决。
通过一遍bfs()我们可以得到迷宫从起点到终点的最短路径数组dis[ ][ ],第二遍我们根据dis[ ][ ]的距离可以从终点往回找,比当前点到起点的距离少1的我们压入队列,然后执行下一次循环即可。
代码:
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace ::std;
const int N = 2e3 + 5;
class SimpleA {
public:
SimpleA(){
};
SimpleA(int sx, int sy, int ex, int ey, int n, int m)
: sx(sx), sy(sy), ex(ex), ey(ey), n(n), m(m) {
}
void scan();
void Path();
private:
int sx, sy, ex, ey, n, m;
static int Map[N][N];
static int dis[N][N];
static int vis[N][N];
static int dir[4][2];
void init();
void intt();
void bfs();
bool judge(int x, int y);
};
int SimpleA::Map[N][N] = {
0};
int SimpleA::dis[N][N] = {
0};
int SimpleA::vis[N][N] = {
0};
int SimpleA::dir[4][2] = {
0, 1, 1, 0, 0, -1, -1, 0};
void SimpleA::init() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
vis[i][j] = 0, dis[i][j] = 0x3f3f3f3f;
}
}
}
void SimpleA::intt() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
vis[i][j] = 0;
}
}
}
void SimpleA::scan() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> Map[i][j];
}
}
}
bool SimpleA::judge(int x, int y) {
if (x > n || y > m || x < 1 || y < 1 || vis[x][y] || Map[x][y] == 1)
return true;
return false;
}
void SimpleA::bfs() {
queue<pair<int, int> > q;
while (!(q.empty())) {
q.pop();
}
init();
pair<int, int> st, en;
st.first = sx, st.second = sy;
q.push(st);
dis[sx][sy] = 0, vis[sx][sy] = 1;
while (!q.empty()) {
st = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int xx = st.first + dir[i][0];
int yy = st.second + dir[i][1];
if (judge(xx, yy))
continue;
dis[xx][yy] = dis[st.first][st.second] + 1;
vis[xx][yy] = 1;
en.first = xx, en.second = yy;
q.push(en);
}
}
}
void SimpleA::Path() {
bfs();
vector<pair<int, int> > way;
queue<pair<int, int> > q;
while (!(q.empty())) {
q.pop();
}
intt();
pair<int, int> st, en;
st.first = ex, st.second = ey;
q.push(st);
while (!q.empty()) {
st = q.front();
way.push_back(st);
q.pop();
for (int i = 0; i < 4; i++) {
int xx = st.first + dir[i][0];
int yy = st.second + dir[i][1];
if (judge(xx, yy))
continue;
if (dis[xx][yy] + 1 == dis[st.first][st.second]) {
en.first = xx, en.second = yy;
vis[xx][yy] = 1;
q.push(en);
break;
}
}
}
int k = way.size() - 1;
if (way[k].first != 1 || way[k].second != 1) {
cout << "Not Find Home !" << endl;
return;
}
for (int i = k; ~i; i--) {
cout << '(' << (way[i].first - 1) << ", " << (way[i].second - 1) << ')'
<< endl;
}
}
int main() {
SimpleA T(1, 1, 5, 5, 5, 5);
T.scan();
T.Path();
return 0;
}