`#include [HTML_REMOVED]
include [HTML_REMOVED]
include [HTML_REMOVED]
include [HTML_REMOVED]
include [HTML_REMOVED]
using namespace std;
typedef pair[HTML_REMOVED] PII;
define x first
define y second
const int N = 210;
int n, m; // 地图的长宽
char g[N][N]; // 储存地图
int dis[N][N]; // 储存每个点到’S’的距离
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int bfs(PII start, PII end)
{
queue[HTML_REMOVED] q; // 对于这个题目q应该定义在bfs()中,如果定义在全局变量中会因为上次的队列残存的变量影响下一次
q.push(start); // 'S'入队
memset(dis, -1, sizeof dis); // 初始化dis[][],避免被上次残存数据影响
dis[start.x][start.y] = 0; // start点已经被走过,距离初始化为0
while(q.size()) // 队列不空
{
PII tmp = q.front(); // 取出队头元素
q.pop(); // 注意:一定要出队,不然会死循环
for(int k = 0;k < 4;k ++) // 上下左右进行试探
{
int x = tmp.x + dx[k], y = tmp.y + dy[k];
if (x < 0 || x >= n || y < 0 || y >= m) continue; // 出界情况
if (g[x][y] == '#') continue; // 遇到障碍物情况
if (dis[x][y] != -1) continue; // 已经走过的情况
dis[x][y] = dis[tmp.x][tmp.y] + 1; // 注意:在判断为出口之前+1,不然距离就会少1
if (end.x == x && end.y == y) return dis[x][y]; // 也可以写成 if(g[x][y] == 'E')
q.push({x , y}); // 入队
}
}
return -1; // 走不到'E',返回-1
}
int main()
{
int T = 0;
scanf("%d", &T);
while(T --)
{
scanf("%d%d", &n, &m);
PII start, end;
memset(g, '#', sizeof g); // 建议初始化g全为'#',虽然对下次没有影响(因为被n,m严格控制)
for (int i = 0;i < n; i++)
{
scanf("%s", g[i]); // 建议一行一行读,一个一个读会出错
for (int j = 0;j < m;j ++)
{
if(g[i][j] == 'S')
{
start = {i , j};
}
else if(g[i][j] == 'E')
{
end = {i , j}; // 结尾的点可以不用记录,因为可以直接通过g[x][y] == 'E'得出
}
}
}
int distance = bfs(start, end);
if(distance == -1)
{
printf("oop!\n");
}
else
{
printf("%d\n", distance);
}
}
return 0;
}`