[广度优先搜索]仙岛求药
Posted yjhqinghua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[广度优先搜索]仙岛求药相关的知识,希望对你有一定的参考价值。
题目大意
题目描述
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。
迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。
下图 显示了一个迷阵的样例及李逍遥找到仙药的路线.
输入格式
输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。
M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义: (1) ‘@’:少年李逍遥所在的位置; (2) ‘.’:可以安全通行的方格; (3) ‘#’:有怪物的方格; (4) ‘*’:仙药所在位置。 当在一行中读入的是两个零时,表示输入结束。
输出格式
对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。
输入输出样例
输入 #1
8 8 .@##...# #....#.# #.#.##.. ..#.###. #.#...#. ..###.#. ...#.*.. .#...### 6 5 .*.#. .#... ..##. ..... .#... ....@ 9 6 .#..#. .#.*.# .####. ..#... ..#... ..#... ..#... #.@.## .#..#. 0 0
输出 #1
10 8 -1
思路
广搜+STL队列 使用结构体变量 Pos 存储坐标 使用二维数组 mp[401][401] 存储地图(答案) 使用常量数组 dx[] dy[] 存储上下左右4个方向 使用 Pos 类型队列维护坐标点的值 使用memset函数每次清空数组的值 使用q.pop()每次清空队列内的值
两份代码
#1 20pts做法(未清空队列)
#include<iostream> #include<cstring> #include<queue> using namespace std; struct Pos int x,y; ; queue <Pos> q; int n,m,x,y,tx,ty,dis[21][21],sx,sy; const int dx[]=1,-1,0,0; const int dy[]=0,0,1,-1; char mp[21][21]; bool vis[21][21]; int bfs(int sx,int sy) q.push((Pos)sx,sy); vis[sx][sy]=true; while(!q.empty()) x=q.front().x; y=q.front().y; q.pop(); if(mp[x][y]==‘*‘) return dis[x][y]; for(int i=0;i<4;i++) tx=x+dx[i]; ty=y+dy[i]; if(tx<=0||tx>n||ty<=0||ty>m) continue; if(mp[tx][ty]==‘#‘||vis[tx][ty]==true) continue; dis[tx][ty]=dis[x][y]+1; vis[tx][ty]=true; q.push((Pos)tx,ty); return -1; int main() while(true) memset(mp,‘ ‘,sizeof(mp)); memset(dis,0,sizeof(dis)); memset(vis,false,sizeof(vis)); cin>>n>>m; if(n==0&&m==0) break; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mp[i][j]; if(mp[i][j]==‘@‘) sx=i; sy=j; cout<<bfs(sx,sy)<<endl; return 0;
#2 AC做法(实现队列清空)
#include<iostream> #include<cstring> #include<queue> using namespace std; struct Pos int x,y; ; queue <Pos> q; int n,m,x,y,tx,ty,dis[21][21],sx,sy; const int dx[]=1,-1,0,0; const int dy[]=0,0,1,-1; char mp[21][21]; bool vis[21][21]; int bfs(int sx,int sy) q.push((Pos)sx,sy); vis[sx][sy]=true; while(!q.empty()) x=q.front().x; y=q.front().y; q.pop(); if(mp[x][y]==‘*‘) return dis[x][y]; for(int i=0;i<4;i++) tx=x+dx[i]; ty=y+dy[i]; if(tx<=0||tx>n||ty<=0||ty>m) continue; if(mp[tx][ty]==‘#‘||vis[tx][ty]==true) continue; dis[tx][ty]=dis[x][y]+1; vis[tx][ty]=true; q.push((Pos)tx,ty); return -1; int main() while(true) memset(mp,‘ ‘,sizeof(mp)); memset(dis,0,sizeof(dis)); memset(vis,false,sizeof(vis)); while(!q.empty()) q.pop(); cin>>n>>m; if(n==0&&m==0) break; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>mp[i][j]; if(mp[i][j]==‘@‘) sx=i; sy=j; cout<<bfs(sx,sy)<<endl; return 0;
本题难度 普及/提高-
以上是关于[广度优先搜索]仙岛求药的主要内容,如果未能解决你的问题,请参考以下文章