题目传送门:http://noi.openjudge.cn/ch0205/7218/
题目描述
阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个R×C的字符矩阵来表示。字符S表示阿尔吉侬所在的位置,字符E表示奶酪所在的位置,字符#表示墙壁,字符.表示可以通行。阿尔吉侬在1个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。
思路
这是一道简单的bfs题。
根据题目,我们需要建立两个二维数组。一个是 char 型的 a数组,用来存储地图。另一个是用来标记是否为重复走过的位置的 vis 数组。接下来就可以开始输入地图开始搜索了。
雷点
- 在开始下一张地图搜索之前,记得先清空队列和vis数组
注:地图数组a是不需要清空的。因为每一轮你都会给重新为地图规定大小并覆盖之前的地图。
完整代码及注释(已AC)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct node{ //定义名为 node 的结构体
int x,y,sum; //x,y记录坐标,sum记录步数
};
char a[1001][1001];
int vis[1001][1001];
int cx[4]={0,0,1,-1}; //方向数组,用来控制方向
int cy[4]={1,-1,0,0};
int n,m,w,xx,yy,xxx,yyy; //xx,yy是起点坐标;xxx,yyy是终点坐标
queue<node> q;
void clean() //用来清空队列的函数(也可以写在主函数里面)
{
while(!q.empty()) q.pop();
}
int main()
{
cin>>w;
while(w--)
{
bool flag=false; //判断能否到达终点的标志
memset(vis,0,sizeof(vis)); //初始化vis数组,将vis数组全部复制为0。
clean(); // 清空队列
cin>>n>>m;
for(int i=1;i<=n;++i) //输入地图
{
for(int j=1;j<=m;++j)
{
cin>>a[i][j];
if(a[i][j]=='S'){xx=i;yy=j;} //记录起点
else if(a[i][j]=='E'){xxx=i;yyy=j;} //记录终点
}
}
node t;
t.x=xx;t.y=yy;t.sum=0; // 将起点入队
vis[xx][yy]=1;
q.push(t);
while(!q.empty()) //搜索
{
t=q.front();
q.pop();
if(t.x==xxx&&t.y==yyy)
{
cout<<t.sum<<endl;
flag=true;
break;
}
node tt;
for(int i=0;i<4;++i)
{
tt.x=t.x+cx[i];
tt.y=t.y+cy[i];
tt.sum=t.sum+1;
if(tt.x>0&&tt.x<=n&&tt.y>0&&tt.y<=m&&a[tt.x][tt.y]!='#'&&!vis[tt.x][tt.y])
{
vis[tt.x][tt.y]=1;
q.push(tt);
}
}
}
if(!flag) cout<<"oop!"<<endl;
}
return 0;
}