题解:
走迷宫问题的升级版
记录起点
把起点加入优先队列中
然后从起点开始BFS,需要破坏一个障碍物的时候 t++,每次走过一个点加入优先队列中
这样就可以保证每次从队列里面出来的是破坏障碍物数最小的了
下面代码中结构体里面的数据变量 z 可以不考虑(我之前用来记录走了几步)
#include <iostream> #include <cstdio> #include <cstdlib> #include <queue> #include <cstring> using namespace std; const int N = 110; int T,n,m; int sx,sy; int maze[N][N]; bool vis[N][N]; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; struct point { int x,y,t,z;///坐标x y 破坏障碍物数 走道当前点需要的步数 point(int x=0,int y=0,int t=0,int z=0,int flag=0):x(x),y(y),t(t),z(z){} bool operator < (const point &a) const { return t>a.t||(t==a.t&&z<a.z); } }; int bfs() { priority_queue <point> que; point zero=point(sx,sy,0,0); vis[sx][sy] = true; que.push(zero); point nex; while(!que.empty()) { point p = que.top(); que.pop(); for(int i = 0; i < 4; i++) { nex.x = p.x + dx[i]; nex.y = p.y + dy[i]; nex.z = p.z+1; if(nex.x <= 0 || nex.x > n || nex.y <= 0 || nex.y > m) return p.t; if(vis[nex.x][nex.y] == false){ if(maze[nex.x][nex.y] == 1) { nex.t = p.t; que.push(nex); vis[nex.x][nex.y] = true; } else if(maze[nex.x][nex.y] == 2) { nex.t = p.t + 1; que.push(nex); vis[nex.x][nex.y] = true; } } } } return -1; } int main() { //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(vis,false,sizeof(vis)); for(int i = 1; i <= n; i++) { char s[105]; scanf("%s",s+1); for(int j = 1; j <= m; j++) { if(s[j] == '@') sx = i , sy = j ,maze[i][j]=-1; else if(s[j] == '.') maze[i][j] = 1; else if(s[j] == '*') maze[i][j] = 2; else if(s[j] == '#') maze[i][j] = 0,vis[i][j]=true; } } printf("%d\n",bfs()); } return 0; }