1.​​题目链接​​。题意就不用说了,中文题。这显示是一个bfs的题,但是这里面有很多坑,写了七八次才写过。

2.首先是两个图,也就是三维的搜索,我们可以采用两个二维的数组分别保存这两个图,首先在第一个图上找到#,然后通过这里进入第二个图,这里就有很多问题了。第一张图穿过去之后对应第二张图上的位置是什么这个很关键。如果第二张图是*,那么显然是不可行的,如果是#,也是不行的,因为根据题意他会在这里死循环。然后就可以bfs了,其实这样也是可以写过的,但是我们可以继续简化这个问题,我们可以采用一个三维的数组,第一维的大小是2,如果当前这一维的数据是0,那么就代表第一个图,如果是1就代表第二个图。这样代码就简化了一点。具体的AC代码:

#include"stdafx.h"
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#pragma warning(disable:4996)
using namespace std;
#define inf (0x7f7f7f7f)
const int maxn = 12;
int c, n, m, t;
char map[2][maxn][maxn];
bool vis[2][maxn][maxn];
struct node
{
int x, y, z;
int step;
};
queue<node> q;
int dir[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } };

bool judge(int x, int y)
{
if (x < 0 || y < 0 || x >= n || y >= m) return false;
return true;
}

bool bfs()
{
bool flag = false;
while (!q.empty())
{
node now = q.front();
q.pop();

if (map[now.z][now.x][now.y] == 'P')
{
if (now.step >= 0)
return true;
else
break;
}

node next;
for (int i = 0; i<4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
next.z = now.z;
next.step = now.step - 1;

if (!judge(next.x, next.y)) continue;

if (map[now.z][next.x][next.y] == '#')
next.z ^= 1;

if (map[next.z][next.x][next.y] != '*' && next.step >= 0 && !vis[next.z][next.x][next.y])
{
vis[next.z][next.x][next.y] = true;
q.push(next);
}
}
}
return false;
}

int main()
{
scanf("%d", &c);
while (c--)
{
scanf("%d %d %d", &n, &m, &t);
memset(vis, false, sizeof(vis));
while (!q.empty()) q.pop();

int i, j, k;
for (i = 0; i<2; i++)
for (j = 0; j<n; j++)
scanf("%s", map[i][j]);
node s;

for (i = 0; i<2; i++)
for (j = 0; j<n; j++)
for (k = 0; k<m; k++)
{
if (map[i][j][k] == 'S')
s.x = j, s.y = k, s.z = i, s.step = t;
else if (map[i][j][k] == '#' && map[1 ^ i][j][k] == '#')
{
map[i][j][k] = '*';
map[1 ^ i][j][k] = '*';
}
else if (map[i][j][k] == '#' && map[1 ^ i][j][k] == '*')
map[i][j][k] = '*';
}
vis[s.z][s.x][s.y] = true;
q.push(s);
if (bfs())
puts("YES");
else
puts("NO");
}
return 0;
}