Is an escape possible? If yes, how long will it take?
L is the number of levels making up the dungeon.
R and C are the number of rows and columns making up the plan of each level.
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.
Escaped in x minute(s).
where x is replaced by the shortest time it takes to escape.
If it is not possible to escape, print the line
Trapped!
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
Escaped in 11 minute(s).
Trapped!
题目大意是:你被困在一个地牢里,现在正在S点,需要走到E点。迷宫有多层,多行,多列,可以向上走,向下走,或者前后左右,求最短路,如果无法到达的话输出无解。这是一道经典的走迷宫问题,只不过从二维迷宫变成了拥有层数的三维迷宫,30^3的数据范围,用一般的深度优先搜索枚举路线是根本不可能了(表示基本只会深搜),果然还是需要用最近才学的广搜勉强试试(汗)。感觉多了一维其实并没有变难多少,只是数组开成了三维,方向增加了上下,增加了一个层数的队列。但是我一开始的代码刚交上去就TLE了,果然广搜还是没有学透。附上超时的代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,l,sum;
char s[35][35][35];
int time[35][35][35];
int dir[6][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
queue<int>X;
queue<int>Y;
queue<int>Z;
bool check(int x,int y,int z)
{
if(x<0||y<0||z<0||x>=l||y>=n||z>=m||s[x][y][z]=='#')
{
return 0;
}
return 1;
}
void bfs()
{
while(!X.empty())
{
s[X.front()][Y.front()][Z.front()]='#';
for(int i=0;i<6;i++)
{
int x=X.front()+dir[i][0];
int y=Y.front()+dir[i][1];
int z=Z.front()+dir[i][2];
if(check(x,y,z)==1)
{
X.push(x);
Y.push(y);
Z.push(z);
time[x][y][z]=time[X.front()][Y.front()][Z.front()]+1;
if(s[x][y][z]=='E')
{
sum=time[x][y][z];
return ;
}
}
}
X.pop();
Y.pop();
Z.pop();
}
}
int main()
{
while(1)
{
scanf("%d %d %d\n",&l,&n,&m);
while(!X.empty())
{
X.pop();
Y.pop();
Z.pop();
}
if(l==0&&m==0&&n==0)
return 0;
for(int i=0;i<l;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<m;k++)
{
scanf("%c",&s[i][j][k]);
if(s[i][j][k]=='S')
{
X.push(i);
Y.push(j);
Z.push(k);
}
}
getchar();
}
getchar();
}
bfs();
if(sum!=0)
{
printf("Escaped in %d minute(s).\n",sum);
}
else
{
printf("Trapped!\n");
}
memset(s,0,sizeof(s));
memset(time,0,sizeof(time));
sum=0;
}
}
检查了半天,原来是找到子结点时没有标记(#),改了之后就AC了~
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,l,sum;
char s[35][35][35];
int time[35][35][35];
int dir[6][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
queue<int>X;
queue<int>Y;
queue<int>Z;
bool check(int x,int y,int z)
{
if(x<0||y<0||z<0||x>=l||y>=n||z>=m||s[x][y][z]=='#')
{
return 0;
}
return 1;
}
void bfs()
{
while(!X.empty())
{
for(int i=0;i<6;i++)
{
int x=X.front()+dir[i][0];
int y=Y.front()+dir[i][1];
int z=Z.front()+dir[i][2];
if(check(x,y,z)==1)
{
X.push(x);
Y.push(y);
Z.push(z);
time[x][y][z]=time[X.front()][Y.front()][Z.front()]+1;
if(s[x][y][z]=='E')
{
sum=time[x][y][z];
return ;
}
s[x][y][z]='#';
}
}
X.pop();
Y.pop();
Z.pop();
}
}
int main()
{
while(1)
{
scanf("%d %d %d\n",&l,&n,&m);
while(!X.empty())
{
X.pop();
Y.pop();
Z.pop();
}
if(l==0&&m==0&&n==0)
return 0;
for(int i=0;i<l;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<m;k++)
{
scanf("%c",&s[i][j][k]);
if(s[i][j][k]=='S')
{
X.push(i);
Y.push(j);
Z.push(k);
s[i][j][k]='#';
}
}
getchar();
}
getchar();
}
bfs();
if(sum!=0)
{
printf("Escaped in %d minute(s).\n",sum);
}
else
{
printf("Trapped!\n");
}
memset(s,0,sizeof(s));
memset(time,0,sizeof(time));
sum=0;
}
}