题解:
走迷宫问题的升级版
记录起点
把起点加入优先队列中
然后从起点开始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;
}