大意:
给一个矩阵 有一个六秒之内会爆炸的炸弹 爆炸事件在数值为4的位置会重置为6
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius' start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius' target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
2 1 1 0 1 1 1 0
1 0 4 1 1 0 4 1
1 0 0 0 0 0 0 1
1 1 1 4 1 1 1 3
问从起点到达终点最少需要的步数
思路:
这个题为bfs 但是有一点比较不好想的就是 可以重复走一些点
所以不能只是单纯的标记而已
我们这样想 由于bfs是按层往外搜索的
对于每一个点 我们如果第二次都到的爆炸时间更长的话 我们就把这个点在此如队列 抽象的把它进行拆点
这样 既能保证步数最小 又能保证重复的时候不会少考虑
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 const int maxn = 10; 8 int n, m; 9 int a[maxn][maxn]; 10 struct Node { 11 int x, y; 12 int le, ti; 13 Node() { 14 x = 0, y = 0, le = 0, ti = 0; 15 } 16 }; 17 18 queue<Node> q; 19 int xx[4] = { 0, 0, 1, -1 }; 20 int yy[4] = { 1, -1, 0, 0 }; 21 int vis[maxn][maxn], tim[maxn][maxn]; 22 23 int solve() { 24 while(!q.empty()) { 25 Node n1 = q.front(); q.pop(); 26 if(a[n1.x][n1.y] == 3) { 27 return n1.ti; 28 } 29 if(n1.le == 1) continue; 30 for(int i = 0; i < 4; i++) { 31 int tx = n1.x + xx[i]; 32 int ty = n1.y + yy[i]; 33 int hah = n1.le - 1; 34 if(a[tx][ty] == 4) hah = 6; 35 if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && a[tx][ty] != 0) { 36 if(!vis[tx][ty] || tim[tx][ty] < hah) { 37 vis[tx][ty] = 1; tim[tx][ty] = hah; 38 Node n2; 39 n2.x = tx; n2.y = ty; 40 n2.le = hah; n2.ti = n1.ti + 1; 41 q.push(n2); 42 } 43 } 44 } 45 } 46 return -1; 47 } 48 49 int main() { 50 int t; 51 scanf("%d",&t); 52 while(t--) { 53 while(!q.empty()) q.pop(); 54 memset(vis, 0, sizeof(vis)); 55 memset(tim, 0, sizeof(tim)); 56 Node n0; 57 scanf("%d %d",&n, &m); 58 for(int i = 1; i <= n; i++) { 59 for(int j = 1; j <= m; j++) { 60 scanf("%d",&a[i][j]); 61 if(a[i][j] == 2) { 62 vis[i][j] = 1; 63 tim[i][j] = 6; 64 n0.x = i; 65 n0.y = j; 66 n0.le = 6; 67 n0.ti = 0; 68 } 69 } 70 } 71 q.push(n0); 72 printf("%d ", solve()); 73 } 74 return 0; 75 }