题目描述(连接:http://codeup.cn/problem.php?id=1102)
小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
小明只能向上下左右四个方向移动。
输入
输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是两个整数N和M(1<=N,M<=100)。
接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
字符的含义如下:
‘S’:起点
‘E’:终点
‘-’:空地,可以通过
‘#’:障碍,无法通过
输入数据保证有且仅有一个起点和终点。
输出
对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。
样例输入
1
5 5
S-###
##—
E#—
—##
样例输出
9
代码
#include <iostream>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
char a[maxn][maxn];///地图字符串数组
int X[4]={1,-1,0,0},Y[4]={0,0,1,-1};///增量数组
int visit[maxn][maxn]={0};///记录数组,记得最后要清0,记录节点是否已经入队,提升程序效率;
int n,m;
struct node
{
int x,y,step=0;
}S,T,Node;///起点S,终点T及中间节点Node
bool check(int x, int y)///检测函数
{
if(x<0||y<0||x>=n||y>=m) return false;///越界
if(visit[x][y]==1||a[x][y]=='#') return false;///访问过了或不可移动
return true;
}
int bfs()///不需要参数,S入队即可
{
queue<node>q;
q.push(S);
visit[S.x][S.y]=1;
while(!q.empty())
{
node top=q.front();///访问队首,能入队的一定符合check的条件(除S外)
q.pop(); ///队首出队
if(top.x==T.x&&top.y==T.y)///到达终点,队列中最早到达终点T的元素
{
return top.step; ///输出步数
}
for(int i=0;i<4;i++)
{
Node.x=top.x+X[i],Node.y=top.y+Y[i];///队首元素的周围元素,用中间节点Node记录
if(check(Node.x,Node.y))
{
Node.step=top.step+1;///层数/步数+1
q.push(Node);
visit[Node.x][Node.y]=1;///记录数组已经入队,别忘了
}
}
}
return -1;///若队列空了都没有达到终点,即没有 return top.step ,说明到达不了终点则输出-1
}
int main()
{
int N;cin>>N;
for(int k=0;k<N;k++)
{
cin>>n>>m;
int i,j;
for( i=0;i<n;i++)
{
getchar();///吸收回车符
for( j=0;j<m;j++)
{
a[i][j]=getchar();///提高输入效率,用cin也可以
if(a[i][j]=='S') {S.x=i,S.y=j;}///获得起点和终点坐标
if(a[i][j]=='E') {T.x=i,T.y=j;}
}
a[i][j+1]='\0';
}
cout << bfs() << endl;
memset(visit,0,sizeof(visit));///visit数组没清空致错
}
return 0;///要放在k循环外面,否则main函数会提前返回0
}