题解 P2360 【地下城主】

· · 题解

其实这是一道很纯的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;
}

还有一点要注意,那就是输入这个地牢的时候坐标特别容易弄错,大家三思而后行啊!