题意:求走出迷宫的最短时间,2代表起点,3代表出口,每次经过4都可以将爆炸时间归0,要在爆炸时间内出去
思路:这里的BFS,vis[][]不再代表是否走过而是距离爆炸的时间,还有就是可以重复的经过一个点,所以我们再次走到这个点的时候,如果能有更长的爆炸时间就入队
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 20;
struct node{
int x,y,t,step;
}tmp;
queue<node> q;
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};
int map[MAXN][MAXN],vis[MAXN][MAXN];
int n,m,x1,y1,ans;
void bfs(){
while (!q.empty()){
tmp = q.front();
q.pop();
int x = tmp.x,y = tmp.y,t = tmp.t - 1,step = tmp.step + 1;
if (tmp.t == 0)
continue;
else {
if (map[x][y] == 3){
ans = tmp.step;
return;
}
if (map[x][y] == 4)
t = 5;
}
for (int i = 0; i < 4; i++){
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && vis[nx][ny] < t && map[nx][ny] != 0){
vis[nx][ny] = t;
tmp.x = nx,tmp.y = ny;
tmp.t = t,tmp.step = step;
q.push(tmp);
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d",&n,&m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++){
scanf("%d",&map[i][j]);
vis[i][j] = 0;
if (map[i][j] == 2)
x1 = i,y1 = j;
}
while (!q.empty())
q.pop();
ans = -1,vis[x1][y1] = 6;
tmp. x = x1,tmp.y = y1,tmp.t = 6,tmp.step = 0;
q.push(tmp);
bfs();
printf("%d\n",ans);
}
return 0;
}