龙神觉得无聊于是来到了地下城,这里是一个巨大的迷宫,有一些可以通行的路、一些不可以通行的墙,还有一些怪物。虽然龙神可以轻易地干掉这些怪物,但他觉得这样就太没意思了,他观察到这些怪物每 k 秒会消失一次,每一秒龙神可以选择向上下左右行走一步(不能在原地不动)。龙神想知道在避开全部怪物的条件下,到达出口所需要的最短时间。
解题思路:
由于求最短时间,那么这个题就相当于一个从起点到终点的bfs,当搜索到终点的时候一定是时间最短的。
考虑每一次入队我们都要将这个点的状态标记为走过,而地图中有的点与时间有关,这样的话我们就在状态里记在t%k的时间走过这个点即可
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n,m,k;
int d[N][N],st[N][N][50];
string g[N];
int sx,sy,ex,ey;
int bfs()
{
queue<PII> q;
d[sx][sy] = 0;
st[sx][sy][0]=1;
q.push({sx, sy});
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
while (q.size())
{
auto t = q.front();
q.pop();
int tt=d[t.first][t.second] + 1;
for (int i = 0; i < 4; i ++ )
{
int x = t.first + dx[i], y = t.second + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m ||st[x][y][tt%k])continue;
if( g[x][y] == '#' ){
continue;
}
if(g[x][y]=='*'&&((tt)%k!=0))continue;
st[x][y][tt%k]=1;
d[x][y] = tt ;
q.push({x, y});
if(x==ex&&y==ey)return tt;
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
memset(d, 0x3f, sizeof d);
memset(st, 0, sizeof st);
cin >> n >> m>>k;
for (int i = 0; i < n; i ++ ){
cin >> g[i];
for (int j = 0; j < m; j ++ )
{
if(g[i][j]=='S')sx=i,sy=j;
if(g[i][j]=='E')ex=i,ey=j;
}
}
cout << bfs() << endl;
}
return 0;
}