这个代码思路比较清晰。
大意:在n×m的地图上,0表示墙,1表示空地,2表示人3表示目的地,4表示有炸弹重启器。炸弹的时间是6,人走一步所需要的时间是1。每次可以上、下、左、右移动一格。当人走到4时如果炸弹的时间不是0,可以重新设定炸弹的时间为6。如果人走到3而炸弹的时间不为0时,成功走出。求人从2走到3的最短时间。这里当走过了4以后就不要重新返回到4,我们把4设为0不能再走;其余的走过后,不进行标记,也就是说他后面还有可能走到这个位置,可能会出现死循环,然而事实不是如此,还没等到你出现,他就return要充分利用到队列和广搜的性质。
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 using namespace std; 5 const int N = 10; 6 int map[N][N], n, m, starti, startj; 7 int dir[][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}}; 8 struct Node 9 { 10 int x, y, curtime, bombtime; 11 }; 12 int dfs() 13 { 14 queue<Node> q; 15 Node now, next; 16 now.x = starti, now.y = startj, now.curtime = 0, now.bombtime = 6; 17 q.push(now); 18 map[now.x][now.y] = 0; 19 while (!q.empty()) 20 { 21 now = q.front(); 22 q.pop(); 23 for (int i = 0; i < 4; ++i) 24 { 25 next.x = now.x + dir[i][0]; 26 next.y = now.y + dir[i][1]; 27 if (next.x>=0 && next.x<n && next.y>=0 && next.y<m && 28 map[next.x][next.y] != 0 && now.bombtime > 1) 29 { 30 if (map[next.x][next.y] == 3) 31 return now.curtime + 1; 32 else if (map[next.x][next.y] == 1) 33 { 34 next.curtime = now.curtime + 1; 35 next.bombtime = now.bombtime - 1; 36 q.push(next); 37 } 38 else if (map[next.x][next.y] == 4) 39 { 40 next.curtime = now.curtime + 1; 41 next.bombtime = 6; 42 q.push(next); 43 map[next.x][next.y] = 0; 44 } 45 } 46 } 47 } 48 return -1; 49 } 50 int main() 51 { 52 int t; 53 scanf("%d", &t); 54 while (t--) 55 { 56 scanf("%d %d", &n, &m); 57 for (int i = 0; i < n; ++i) 58 for (int j = 0; j < m; ++j) 59 { 60 scanf("%d", &map[i][j]); 61 if (map[i][j] == 2) 62 starti = i, startj = j; 63 } 64 printf("%d\n", dfs()); 65 } 66 return 0; 67 }