用BFS简单些,无非就是吧二维数组变成三维数组,过程和其他求是否连通的题目大同小异。
坐标变化是6.
不过这题我写的时候直接在标记出压缩成一行判断,老是得不到正确结果,再看了大神的代码后,增加了check()这一判断函数,就奇迹般的ac了,所以以后对于复杂的判断最好写一个判断函数。
另外我发现大神代码的另一个优点,能减少输入后便利取S和E的循环次数,这种小的优化很重要,值得借鉴。(下方代码中“藏起来了”);
学习编程要虚心,谦逊,否则进步很慢,人家强我就跟人家学嘛,谁不是学过来的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
const int N = 33;
char c[N][N][N];
bool vis[N][N][N];
int px[6]= {-1,1,0,0,0,0};
int py[6]= {0,0,-1,1,0,0};
int pz[6]= {0,0,0,0,-1,1};
int n,m,p;
int bx,by,bz,ex,ey,ez;
struct note {
int x,y,z;
int time;
} s;
int check(int x,int y,int z) {
if(x<0 || y<0 || z<0 || x>=n || y>=m || z>=p)
return 1;
else if(c[x][y][z] == '#')
return 1;
else if(vis[x][y][z])
return 1;
return 0;
}
int bfs() {
s.x=bx,s.y=by,s.z=bz,s.time=0;
queue<note>Q;
Q.push(s);
vis[bx][by][bz]=true;
while(!Q.empty()) {
note now,end;
printf("%d\n",Q.size());
now=Q.front();
Q.pop();
if(now.x==ex&&now.y==ey&&now.z==ez)
return now.time;
for(int l=0; l<6; l++) {
end=now;
end.x=now.x+px[l];
end.y=now.y+py[l];
end.z=now.z+pz[l];
if(check(end.x,end.y,end.z))//标记标记标记
continue;
end.time=end.time+1;
vis[end.x][end.y][end.z]=true;
Q.push(end);
}
}
return -1;
}
int main() {
while(scanf("%d%d%d",&n,&m,&p),n||m||p) {
memset(vis,false,sizeof(vis));
for(int i = 0; i<n; i++) {
for(int j = 0; j<m; j++) {
scanf("%s",c[i][j]);
for(int r = 0; r<p; r++) {
if(c[i][j][r] == 'S') {
bx = i,by = j,bz = r;
} else if(c[i][j][r] == 'E') {
ex = i,ey = j,ez = r;
}
}
}
}
int ans=bfs();
if(ans==-1)
printf("Trapped!\n");
else
printf("Escaped in %d minute(s).\n",ans);
}
return 0;
}