题目描述:
走迷宫是很有趣的一种游戏,能够锻炼人的记忆力和思维.现在,HK被困在一个迷宫里面了,请你帮助他找到一条最短的路径,能够让他走出迷宫.
迷宫使用一个N*M的矩阵来描述,矩阵中用'.'代表空格可以通行,用'*'代表障碍物,用'S'代表出发点,用'T'代表出口.例如下面的一个矩阵就描述了一个8*8的迷宫
.....T..
..*****.
......*.
*.***.*.
......*.
.****.*.
S..*....
........
每个字符代表1个格子,HK只能在格子间按上下左右的方向移动
输入格式:
每个输入文件只包含一组输入数据.
每组数据第一行是两个正整数N和M(N,M<=100).
接着是一个N*M的矩阵.
输出格式:
如果HK能够走出迷宫,输出最少需要的步数;否则输出-1.
输入样例:
8 8 .....T.. ..*****. ......*. *.***.*. ......*. .****.*. S..*.... ........输出样例:
11分析思路:
分别从S点和T点开始搜索,给这两个点的搜索分别开两个标记数组,当两个标记数组有重合时,则搜索到最短路径,当两个标记数组不相遇,则表示没有相应的路径,但还是不明白为什么一定要开两个dist数组。。。这题用单向广搜也可以做出来,用双向广搜只是为了练习一下双向。
源代码如下:
//为什么不能用一个数组标记,一个距离数组计算?
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 100 + 10
struct Node {
int x, y;
};
char MAPT[MAXN][MAXN];
int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1};
int svis[MAXN][MAXN], evis[MAXN][MAXN];
int sdist[MAXN][MAXN], edist[MAXN][MAXN];
int M, N;
int check(int xx, int yy) {
int flag = 1;
if (xx < 0 || xx >= M || yy < 0 || yy >= N) flag = 0;
return flag;
}
int Double_BFS(int sx, int sy, int ex, int ey) {
queue<Node> sq, eq;
Node spre, snow, epre, enow;
int i, j;
snow.x = sx; snow.y = sy;
enow.x = ex; enow.y = ey;
sq.push(snow); svis[snow.x][snow.y] = 1,
eq.push(enow); evis[enow.x][enow.y] = 1;
while (!sq.empty() && !eq.empty()) {
spre = sq.front(); sq.pop();
epre = eq.front(); eq.pop();
for (i = 0; i < 4; i++) {
snow.x = spre.x + dir[i][0];
snow.y = spre.y + dir[i][1];
enow.x = epre.x + dir[i][0];
enow.y = epre.y + dir[i][1];
if (check(snow.x, snow.y) && !svis[snow.x][snow.y] && MAPT[snow.x][snow.y] != '*') {
sq.push(snow);
svis[snow.x][snow.y] = 1;
sdist[snow.x][snow.y] = sdist[spre.x][spre.y] + 1;
if (evis[snow.x][snow.y]) return sdist[snow.x][snow.y] + edist[snow.x][snow.y];
}
if (check(enow.x, enow.y) && !evis[enow.x][enow.y] && MAPT[enow.x][enow.y] != '*') {
eq.push(enow);
evis[enow.x][enow.y] = 1;
edist[enow.x][enow.y] = edist[epre.x][epre.y] + 1;
if (svis[enow.x][enow.y]) return sdist[enow.x][enow.y] + edist[enow.x][enow.y];
}
}
}
return -1;
}
int main() {
FILE *p = freopen("test.txt", "r", stdin);
int i, j;
while (~scanf("%d%d", &M, &N)) {
for (i = 0; i < M; i++) {
scanf("%s", MAPT[i]);
}
memset(svis, 0, sizeof(svis));
memset(evis, 0, sizeof(evis));
memset(sdist, 0, sizeof(sdist));
memset(edist, 0, sizeof(edist));
int sx = 0, sy = 0, ex = 0, ey = 0;
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
if (MAPT[i][j] == 'S') {
sx = i; sy = j;
}
if (MAPT[i][j] == 'T') {
ex = i; ey = j;
}
}
}
int ans = 0;
ans = Double_BFS(sx, sy, ex, ey);
printf("%d\n", ans);
}
return 0;
}