1 条题解
-
0
自动搬运
来自洛谷,原作者为

二元长天笑
**搬运于
2025-08-24 21:36:47,当前版本为作者最后更新于2017-06-26 14:07:48,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
其实这是一道很纯的bfs,但是由于维度加了一维,内存可能会相应的加大,但是没有关系,还是按原来的套路走就好了,我这里用的是纯手工队列,然后发现内存并没有爆,所以小伙伴们放心的开吧。现在回到正题,三维的bfs对于二维的来说,只是多了一个z坐标,所以我们在增加子节点的时候给他多搜索一个方向,如下:
x1=x[head]+d3[i]; y1=y[head]+d1[i]; z1=z[head]+d2[i];然后就跟二维的套路一样,判断是否走过和是否越界,都没有的话就入队,如下:
if(a[x1][y1][z1]&&x1>=1&&x1<=l&&y1>=1&&y1<=n&&z1>=1&&z1<=m) { tail++; a[x1][y1][z1]=0; x[tail]=x1; y[tail]=y1; z[tail]=z1; f[tail]=head;f数组在这里用来统计步数。然后再判断是否到达,如下:
if(x1==en1&&y1==en2&&z1==en3) { while(f[tail]) //这是一个“非递归”,用来找步数。 { tail=f[tail]; sum++; } cout<<"Escaped in "<<sum<<" minute(s)."<<endl; return 0; //找到了就直接输出结束 } }如果一直没有找到,队首就会追上队尾,然后就结束循环,在最后再输出无法到达。
全部代码如下:
#include<iostream> #include<string> using namespace std; string s; int n,m,l,be1,be2,be3,en1,en2,en3,x[10001],y[10001],z[10001],d1[6]={1,-1,0,0,0,0},d2[6]={0,0,-1,1,0,0},d3[6]={0,0,0,0,1,-1},tail=1,head=0,x1,y1,z1,f[10001],sum; bool a[31][31][31]={0}; int main() { cin>>l>>n>>m; for(int i=1;i<=l;i++) for(int j=1;j<=n;j++) { cin>>s; for(int k=0;k<m;k++) { if(s[k]=='.') a[i][j][k+1]=1; if(s[k]=='S') { be1=i;be2=j;be3=k+1; } if(s[k]=='E') { en1=i;en2=j;en3=k+1; a[i][j][k+1]=1; } } } x[tail]=be1,y[tail]=be2,z[tail]=be3; do { head++; for(int i=0;i<6;i++) { x1=x[head]+d3[i]; y1=y[head]+d1[i]; z1=z[head]+d2[i]; if(a[x1][y1][z1]&&x1>=1&&x1<=l&&y1>=1&&y1<=n&&z1>=1&&z1<=m) { tail++; a[x1][y1][z1]=0; x[tail]=x1; y[tail]=y1; z[tail]=z1; f[tail]=head; if(x1==en1&&y1==en2&&z1==en3) { while(f[tail]) { tail=f[tail]; sum++; } cout<<"Escaped in "<<sum<<" minute(s)."<<endl; return 0; } } } }while(head<tail); cout<<"Trapped!"<<endl; }还有一点要注意,那就是输入这个地牢的时候坐标特别容易弄错,大家三思而后行啊!
- 1
信息
- ID
- 1362
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者