双向广搜示例:走迷宫1
2015-07-25 19:42
246 查看
题目描述:
走迷宫是很有趣的一种游戏,能够锻炼人的记忆力和思维.现在,HK被困在一个迷宫里面了,请你帮助他找到一条最短的路径,能够让他走出迷宫.
迷宫使用一个N*M的矩阵来描述,矩阵中用'.'代表空格可以通行,用'*'代表障碍物,用'S'代表出发点,用'T'代表出口.例如下面的一个矩阵就描述了一个8*8的迷宫
.....T..
..*****.
......*.
*.***.*.
......*.
.****.*.
S..*....
........
每个字符代表1个格子,HK只能在格子间按上下左右的方向移动
输入格式:
每个输入文件只包含一组输入数据.
每组数据第一行是两个正整数N和M(N,M<=100).
接着是一个N*M的矩阵.
输出格式:
如果HK能够走出迷宫,输出最少需要的步数;否则输出-1.
输入样例:
输出样例:
分析思路:
分别从S点和T点开始搜索,给这两个点的搜索分别开两个标记数组,当两个标记数组有重合时,则搜索到最短路径,当两个标记数组不相遇,则表示没有相应的路径,但还是不明白为什么一定要开两个dist数组。。。这题用单向广搜也可以做出来,用双向广搜只是为了练习一下双向。
源代码如下:
走迷宫是很有趣的一种游戏,能够锻炼人的记忆力和思维.现在,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; }
相关文章推荐
- 基于MFC框架插件模式
- 编码风格
- 面向对象4
- 笔记
- android studio上imageloader初探
- 面向对象3
- Spring AOP 异常:IllegalArgumentException: error at ::0 can't find referenced pointcut
- Ubuntu中查找与Launcher图标所对应的命令
- hdu 4284——Travel
- 面向对象2
- Struts2的配置文件——web.xml
- 编程领域感悟
- xcode调试命令
- java之可变参数
- 与阿根廷一起学习Java Web四个发展:对于信息传输和信息传输
- ECharts学习总结(五):echarts的Option概览
- java之可变参数
- 面向对象1
- 一道小小的内存申请面试题
- bloom filter