传送门

如题所示,一个两层的迷宫,骑士从S(0,0,0)进入迷宫,要在t时间内到达公主的所在地P,每次只能上下左右移动,'*'表示墙,'#'表示时空传输机,可以瞬间完成迷宫层次切换,即当骑士处于第1层的(x,y)位置时,可以传输到第2层的(x,y)位置
此题的解法很容易想到,bfs就可以,但是处理的情况稍微多了一点,有一种比较坑的情况,题目是有讲的,就是传输机的另一边是堵墙,骑士们会撞死

还有一种比较坑的地方是传输机的另一边还是传输机,这种情况就是陷入无穷无尽的传输中,本来以为把传输机的位置都标记为已访问过就万事大吉了,可惜还是太单纯了一点,WA了一次,后来就拿出来另外考虑了。

附代码如下:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 15;
struct maze
{
    int x,y,z,t;
    maze(){}
    maze(int x1,int y1,int z1,int t1):x(x1),y(y1),z(z1),t(t1){}
};
char a[2][N][N];
bool v[2][N][N];
int n,m,maxt,g[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool BFS(int x,int y,int z,int t)
{
    queue<maze> q;
    memset(v,false,sizeof(v));
    v[z][x][y]=true;
    q.push(maze(x,y,z,t));
    while(!q.empty())
    {
        maze u = q.front();
        q.pop();
        for(int i = 0;i < 4; i++)
        {
            x = u.x + g[i][0];
            y = u.y + g[i][1];
            z = u.z;
            t = u.t + 1;
            if(x >= 0 && x < n && y >= 0 && y < m && z >= 0 && z <= 1 && !v[z][x][y])
            {
                if(a[z][x][y] == '#')
                {
                    v[z][x][y] = true;
                    if(a[z^1][x][y] != '*')
                    {
                        if(a[z^1][x][y] == 'P')
                        {
                            if(t <= maxt)
                                return true;
                            else
                                return false;
                        }
                        if(a[z^1][x][y] != '#')
                            q.push(maze(x,y,z^1,t));
                        v[z^1][x][y] = true;
                    }
                }
                else if(a[z][x][y] == 'P')
                {
                    if(t <= maxt)
                        return true;
                    else
                        return false;
                }
                else if(a[z][x][y] != '*')
                {
                    v[z][x][y] = true;
                    q.push(maze(x,y,z,t));
                }
            }
        }
    }
    return false;
}
int main()
{
    int c;
    scanf("%d",&c);
    while(c--)
    {
        scanf("%d %d %d",&n,&m,&maxt);
        for(int i = 0;i < n; i++)
            scanf("%s",a[0][i]);
        for(int i = 0;i < n; i++)
            scanf("%s",a[1][i]);
        if(BFS(0,0,0,0))
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}