很显然对于这个题来说,有的点可能需要重复走(比如旁边有Bomb-Reset-Equipment,可能你需要去一下再回来),所以标记每个点的时候应该记录访问该点时的剩余时间,如果下一次剩余时间更多则可以加入队列,否则的话加入这个点是没有意义的(因为花费的总步数更多但是剩余的时间没有变多)。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 7 const int N = 8; 8 int maze[N][N]; 9 int visit[N][N]; 10 int dx[] = { 0, 0, 1, -1 }; 11 int dy[] = { 1, -1, 0, 0 }; 12 int sx, sy, ex, ey; 13 int n, m; 14 15 bool ok( int x, int y ) 16 { 17 return x >= 0 && x < n && y >= 0 && y < m && maze[x][y] != 0; 18 } 19 20 struct Node 21 { 22 int x, y, step; 23 Node(){} 24 Node( int _x, int _y, int _step ) 25 { 26 x = _x, y = _y, step = _step; 27 } 28 }; 29 30 queue<Node> q; 31 32 int bfs() 33 { 34 while ( !q.empty() ) q.pop(); 35 memset( visit, 0, sizeof(visit) ); 36 visit[sx][sy] = 6; 37 q.push( Node( sx, sy, 0 ) ); 38 while ( !q.empty() ) 39 { 40 Node cur = q.front(); 41 q.pop(); 42 if ( cur.x == ex && cur.y == ey ) return cur.step; 43 if ( visit[cur.x][cur.y] == 1 ) continue; 44 for ( int i = 0; i < 4; i++ ) 45 { 46 int xx = cur.x + dx[i]; 47 int yy = cur.y + dy[i]; 48 if ( ok( xx, yy ) ) 49 { 50 int r = visit[cur.x][cur.y] - 1; 51 if ( maze[xx][yy] == 4 ) r = 6; 52 if ( r > visit[xx][yy] ) 53 { 54 q.push( Node( xx, yy, cur.step + 1 ) ); 55 visit[xx][yy] = r; 56 } 57 } 58 } 59 } 60 return -1; 61 } 62 63 int main () 64 { 65 int t; 66 scanf("%d", &t); 67 while ( t-- ) 68 { 69 scanf("%d%d", &n, &m); 70 for ( int i = 0; i < n; i++ ) 71 { 72 for ( int j = 0; j < m; j++ ) 73 { 74 scanf("%d", &maze[i][j]); 75 if ( maze[i][j] == 2 ) 76 { 77 sx = i; 78 sy = j; 79 maze[i][j] = 1; 80 } 81 else if ( maze[i][j] == 3 ) 82 { 83 ex = i; 84 ey = j; 85 maze[i][j] = 1; 86 } 87 } 88 } 89 int ans = bfs(); 90 printf("%d ", ans); 91 } 92 return 0; 93 }