这道题目虽然一看就是dfs,但是感觉太坑了,经过我查了下别人的总结总结出以下几点
- 如果第一层是#,第二层也是#,那么就无法进行传送
- 起点一定在0,0,0
- 题目说是T时刻到达终点,但并不是如此的,可以提前到达,就算比如是13到达,要求14秒那也没事,不要求插值是偶数
- 传送下去的点要判断是否经过(这是细节,不是坑点)
- 终点不只是在第二层,也可以在第一层
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n, m, t;
int flag;
char w[2][12][12];
int vis[2][12][12];
int to[4][2]{ 0,1,0,-1,1,0,-1,0 };//写错了
void dfs(int x, int y, int f)
{
if (flag)
return;
if (vis[f][x][y] <= t && w[f][x][y] == 'P')
{
flag = 1;
return;
}
if (vis[f][x][y] >= t)
return;
int dx, dy;
for (int i = 0; i<4; i++)
{
dx = x + to[i][0];
dy = y + to[i][1];
if ((w[f][dx][dy] == '.'|| w[f][dx][dy] == 'P') && !vis[f][dx][dy]&&dx>=0&&dx<n&&dy>=0&&dy<m)
{
vis[f][dx][dy] = vis[f][x][y] + 1;
dfs(dx, dy, f);
vis[f][dx][dy] = 0;
}
if (w[f][dx][dy] == '#' && !vis[f][dx][dy] && !vis[(f+1)%2][dx][dy] && dx >= 0 && dx<n&&dy >= 0 && dy<m)
{
vis[f][dx][dy] = vis[f][x][y]+1;
if (f == 1)
{
vis[0][dx][dy] = vis[f][x][y]+1;
dfs(dx, dy, 0);
vis[0][dx][dy] = 0;
}
else
{
vis[1][dx][dy] = vis[f][x][y]+1;
dfs(dx, dy, 1);
vis[1][dx][dy] = 0;
}
vis[f][dx][dy] = 0;
}
}
}
int main()
{
int N;
cin >> N;
while (N--)
{
memset(vis, 0, sizeof(vis));
flag = 0;
cin >> n >> m >> t;
for (int i = 0; i<n; i++)
{
for (int j = 0; j<m; j++)
{
cin >> w[0][i][j];
}
}
for (int i = 0; i<n; i++)
{
for (int j = 0; j<m; j++)
{
cin >> w[1][i][j];
if (w[1][i][j] == '#'&&w[0][i][j] == '*')
w[1][i][j] = '*';
if (w[0][i][j] == '#'&&w[1][i][j] == '*')
w[0][i][j] = '*';
if(w[0][i][j] == '#'&&w[1][i][j] == '#')
w[0][i][j] = '*', w[1][i][j] = '*';
}
}
int x, y;
int dx, dy;
for(int z=0;z<2;z++)
for (int i = 0; i<n; i++)
for (int j = 0; j<m; j++)
{
if (w[z][i][j] == 'P')
dx = i, dy = j;
}
x = 0;
y = 0;
dfs(x, y, 0);
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}