这个题用普通的队列也可以,关键的地方是 对于炸弹重置装置只能访问一次,虽然题中允许访问多次。
我的代码:
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n,m;
int a[50][50];
int stx,sty,endx,endy;
int flag;
struct node{
int x,y;
int time;
int step;
};
node ans;
struct cmp{
bool operator()(node x,node y) // x.step比y.step优先级小 返回true
{
return x.step > y.step;
}
};
int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};
void bfs()
{
priority_queue<node,vector<node>,cmp> q;
node f ;
f.x = stx;
f.y = sty;
f.time = 6;
f.step = 0;
q.push(f);
while(!q.empty())
{
node h = q.top();
q.pop();
for(int i = 0;i < 4;++i)
{
node t;
int tx = h.x + dx[i];
int ty = h.y + dy[i];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty])
{
if(a[tx][ty] == 4 && h.time - 1)
{
t.x = tx;
t.y = ty;
t.time = 6;
t.step = h.step + 1;
a[tx][ty] = 0;
q.push(t);
}
else if(a[tx][ty] == 1 || a[tx][ty] == 3)
{
t.x = tx;
t.y = ty;
t.time = h.time - 1;
t.step = h.step + 1;
if(tx == endx && ty == endy && t.time)
{
flag = 1;
ans = t;
return ;
}
if(t.time){
q.push(t);
}
}
}
}
}
}
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
scanf("%d%d",&n,&m);
for(int i = 0;i < n;++i)
for(int j = 0;j < m;++j){
scanf("%d",&a[i][j]);
if(a[i][j] == 2)
{
stx = i;
sty = j;
}
else if(a[i][j] == 3)
{
endx = i;
endy = j;
}
}
flag = 0;
bfs();
if(flag)
printf("%d\n",ans.step);
else
printf("-1\n");
}
return 0;
}