题意
给一个k×n×m的迷宫,和起点以及终点,迷宫中有一部分位置被石头占领了无法通过,每次只能向东南西北或者上层下层移动,要求从起点能否走到终点,如果能走到,输出所用的最小步数。
思路
每次搜索的方向可以放在常数数组里,因为有三维,所以需要开三个常数数组,每个数组的下标为i的元素就代表了一次行动的方向,然后用bfs搜索,如果搜到了终点就输出答案(因为bfs可以保证第一次搜到某一个点的路径一定是最优的)
注意:由于有多组测试数据,因此用来保存信息的数组每次都要初始化,不然会对下一组数据的结构产生影响(好长一段时间都在做luogu上的oi题,这方面注意得少了,今天算是吃了个大亏)
8说了,上代码
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
char map[31][31][31];
bool vis[31][31][31];
int step[31][31][31];
int dx[] = {0, 0, 0, 0, 1, -1};//6种移动方案,对应6个元素
int dy[] = {0, 0, 1, -1, 0, 0};
int dz[] = {1, -1, 0, 0, 0, 0};
int l, r, c;
int ans;
int sx, sy, sk, ex, ey, ek;
int bfs(int x, int y, int k)
{
queue<int> qxyk;
vis[k][x][y] = true;
qxyk.push(x);
qxyk.push(y);
qxyk.push(k);
while(!qxyk.empty())
{
int xx = qxyk.front();
qxyk.pop();
int yy = qxyk.front();
qxyk.pop();
int kk = qxyk.front();
qxyk.pop();
if(xx == ex && yy == ey && kk==ek)
{
return step[kk][xx][yy];
}
for(int i=0; i<6; i++)
{
int nx = xx+dx[i];
int ny = yy+dy[i];
int nk = kk+dz[i];
if(map[nk][nx][ny] != '#' && !vis[nk][nx][ny] && nx>=1 && nx<=r && ny>=1 && ny<=c && nk >= 1 && nk<=l)
{
//cout<<nk<<" "<<nx<<" "<<ny<<endl;
vis[nk][nx][ny] = true;
step[nk][nx][ny] = step[kk][xx][yy]+1;
qxyk.push(nx);
qxyk.push(ny);
qxyk.push(nk);
}
}
}
return -1;
}
int main()
{
while(cin>>l>>r>>c, l&&r&&c)
{
memset(vis, false, sizeof(vis));
memset(step, 0, sizeof(step));
ans = -1;
for(int k=1; k<=l; k++)
{
for(int i=1; i<=r; i++)
{
for(int j=1; j<=c; j++)
{
cin>>map[k][i][j];
if(map[k][i][j] == 'S')
{
sx = i;
sy = j;
sk = k;
}
else if(map[k][i][j] == 'E')
{
ex = i;
ey = j;
ek = k;
}
}
}
}
//cout<<sx<<sy<<ex<<ey<<sk<<ek<<endl;
ans = bfs(sx, sy, sk);
if(ans == -1)
cout<<"Trapped!"<<endl;
else
cout<<"Escaped in "<<ans<<" minute(s)."<<endl;
}
return 0;
}