传送门: https://uva.onlinejudge.org/external/16/1600.pdf
多状态广搜
网上题解: 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰到墙,当前的k减去1,碰到0,当前的k变成最初的k。
vis[x][y][z] x, y代表坐标 z表示k 当为真时说明该点剩余穿墙次数为k的状态已出现过
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef struct Node{ 5 int x, y, step, k; 6 } node; 7 const int MAXN = 25; 8 const int INF = 0x3f3f3f3f; 9 const int cx[] = {-1, 1, 0, 0}; 10 const int cy[] = {0, 0, -1, 1}; 11 int n, m, k, ans; 12 int maze[MAXN][MAXN]; 13 int vis[MAXN][MAXN][MAXN]; 14 15 void bfs(){ 16 queue<node> q; 17 while(!q.empty()) q.pop(); 18 node cur ; 19 cur.x = cur.y = 1; 20 cur.step = 0; 21 cur.k = k; 22 q.push(cur); 23 vis[cur.x][cur.y][cur.k] = 1; 24 while(!q.empty()){ 25 cur = q.front(); 26 q.pop(); 27 int x = cur.x, y = cur.y; 28 if(x == n && y == m){ 29 ans = cur.step; 30 return ; 31 } 32 node now; 33 if(cur.k >= 0){ 34 for(int i = 0; i < 4; ++i){ 35 now.x = x + cx[i], now.y = y + cy[i]; 36 now.step = cur.step + 1; 37 now.k = maze[now.x][now.y] ? cur.k - 1 : k; 38 if(now.x < 1 || n < now.x || now.y < 1 || m < now.y || vis[now.x][now.y][now.k]) continue; 39 if(now.k >= 0){ 40 vis[now.x][now.y][now.k] = 1; 41 q.push(now); 42 } 43 } 44 } 45 } 46 } 47 48 int main(){ 49 int t; 50 cin >> t; 51 while(t--){ 52 cin >> n >> m >> k; 53 memset(vis, 0, sizeof(vis)); 54 memset(maze, 0, sizeof(maze)); 55 for(int i = 1; i <= n; ++i) 56 for(int j = 1; j <= m; ++j) 57 cin >> maze[i][j]; 58 ans = -1; 59 bfs(); 60 cout << ans << endl; 61 } 62 return 0; 63 }