版权声明:转载请注明出处:https://blog.csdn.net/qq1013459920 https://blog.csdn.net/qq1013459920/article/details/84797688
1221: 迷宫问题
时间限制: 1 内存限制: 32 MB
题目描述
小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
小明只能向上下左右四个方向移动。
输入
输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
每组输入的第一行是两个整数N和M(1<=N,M<=100)。
接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
字符的含义如下:
‘S’:起点
‘E’:终点
‘-’:空地,可以通过
‘#’:障碍,无法通过
输入数据保证有且仅有一个起点和终点。
输出
对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。
样例输入
1 5 5 S-### ----- ##--- E#--- ---##
样例输出
9
这题不能直接用STL标准库中的queue,会爆内存,要自己写个简单的队列(大小100 * 100,最多入队情况)
AC Code:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
using namespace std;
static const int dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
char maps[105][105];
int sx, sy, ex, ey;
int n, m, head, tail;
bool flag;
bool vis[105][105];
struct Path{
public :
int x, y, t;
};
struct Path que[105 * 105];
inline int read(){int x = 0, f = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
bool is_bound(Path p){ //边界判断 & 障碍判断 & 重复点判断
return (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m && !vis[p.x][p.y] && maps[p.x][p.y] != '#');
}
void bfs(){
vis[sx][sy] = true;
Path p1;
head = 1, tail = 1;
que[tail].x = sx, que[tail].y = sy, que[tail].t = 0;
tail++;
while(head < tail){ //队列存在新元素
for(int i = 0; i < 4; i++){
p1.x = que[head].x + dir[i][0];
p1.y = que[head].y + dir[i][1];
p1.t = que[head].t + 1;
if(!is_bound(p1)) continue;
if(p1.x == ex && p1.y == ey){
flag = true;
printf("%d\n", p1.t);
return;
}
vis[p1.x][p1.y] = true;
que[tail].x = p1.x, que[tail].y = p1.y, que[tail++].t = p1.t;
}
head++;
}
}
int main(){
int T = read();
while(T--){
flag = false;
memset(vis, false, sizeof(vis));
n = read(); m = read();//这里的read吃掉了一个回车,所以不用getchar了
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
scanf("%c", &maps[i][j]);
if(maps[i][j] == 'S'){
sx = i, sy = j;
}
if(maps[i][j] == 'E'){
ex = i, ey = j;
}
}
getchar();
}
bfs();
if(!flag) printf("-1\n");
}
return 0;
}
STL标准库queue(内存超限)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
using namespace std;
static const int dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
char maps[55][55];
int sx, sy, ex, ey;
int n, m;
bool flag;
bool vis[55][55];
struct Path{
public :
int x, y, t;
};
inline int read(){int x = 0, f = 1;char ch = getchar();
while(ch > '9' || ch < '0') {if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
bool is_bound(Path p){
return (p.x >= 0 && p.x < n && p.y >= 0 && p.y < m && !vis[p.x][p.y] && maps[p.x][p.y] != '#');
}
void bfs(){
queue<Path>q;
Path p1, p2;
p1.x = sx, p1.y = sy, p1.t = 0;
q.push(p1);
vis[sx][sy] = true;
while(!q.empty()){
p1 = q.front();
q.pop();
for(int i = 0; i < 4; i++){
p2.x = p1.x + dir[i][0];
p2.y = p1.y + dir[i][1];
p2.t = p1.t + 1;
if(!is_bound(p2)) continue;
if(p2.x == ex && p2.y == ey){
flag = true;
printf("%d\n", p2.t);
return ;
}
vis[p2.x][p2.y] = true;
q.push(p2);
}
}
}
int main(){
int T = read();
while(T--){
flag = false;
memset(vis, false, sizeof(vis));
n = read(); m = read();
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
scanf("%c", &maps[i][j]);
if(maps[i][j] == 'S'){
sx = i, sy = j;
}
if(maps[i][j] == 'E'){
ex = i, ey = j;
}
}
getchar();
}
bfs();
if(!flag) printf("-1\n");
}
return 0;
}