将二维地图加上一个钥匙编号变成三维。这样在得到钥匙之后还能去广搜得到下一个钥匙或者救到师父。
在这里面没有明确的结束条件,要保证不走回路就是不能走比他小得路。
#include <bits/stdc++.h> using namespace std; struct Node { int x, y, z; }; const int maxn = 100+10; char ch[maxn][maxn]; int vis[maxn][maxn][10]; queue<struct Node> q; int begin_x, begin_y; int n, m; int ans = INT_MAX; int mv[4][2] { {-1,}, {1,0}, {0,1}, {0,-1} }; void BFS() { q.push({begin_x, begin_y, 0}); vis[begin_x][begin_y][0] = 0; while (!q.empty()) { Node p = q.front(); q.pop(); int x = p.x;int y=p.y;int z = p.z; if (ch[p.x][p.y]=='T'&&z == m) ans = min(ans, vis[p.x][p.y][p.z]); for (int i=0;i<4;i++) { int next_x=x+mv[i][0]; int next_y = y+mv[i][1]; int next_z = z; if (next_x<0||next_x>=n||next_y<0||next_y>=n||ch[next_x][next_y]=='#') continue; if ((ch[next_x][next_y]-'0')==(next_z+1)) next_z++; if (ch[next_x][next_y]=='S') { if (vis[next_x][next_y][next_z]>vis[x][y][z]+2) { vis[next_x][next_y][next_z] = vis[x][y][z]+2; q.push({next_x, next_y, next_z}); } } else if (ch[next_x][next_y]!='S'&&vis[next_x][next_y][next_z]>vis[x][y][z]+1){ vis[next_x][next_y][next_z] = vis[x][y][z]+1; q.push({next_x, next_y, next_z}); } } } } int main() { cin>>n>>m; for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { cin>>ch[i][j]; if (ch[i][j]=='K') { begin_x = i; begin_y = j; } } } memset(vis, 0x3f, sizeof(vis)); BFS(); if (ans == INT_MAX) { cout<<"impossible"; } else { cout<<ans; } return 0; }