题意:给你一个迷宫地图你在迷宫里并携带一个定时炸弹,炸弹将在6秒后爆炸每次你只能上下左右走,且每步耗时一秒,地图里2代表你的初始位置,3代表迷宫的出口,1表示可以走的路,0表示墙,4表示定时炸弹时间重置装置(爆炸时间重新变为6秒),你到达出口或4位置炸弹剩余时间必须大于0秒,求走出迷宫的最短时间,走不出输出-1。
思路:用一个结构体来存地图上每个点对应的状态(坐标位置x,y,剩余时间:time,走了多少步),利用广搜来一步一步将结构体结点入队列并进行判断。 代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int mp[10][10];
int n,m;
struct Node{
int x;
int y;
int time;
int step;
}Start,End;
bool chage(Node N,int max_x,int max_y) //判断该点是否可走
{
if(N.x>=1&&N.x<=max_x&&N.y>=1&&N.y<=max_y)
{
if(mp[N.x][N.y]!=0)
return true;
}
return false;
}
int bfs(Node Sstart,Node Eend,int max_x,int max_y)
{
queue<Node> Q;
Node Vnow,Vnext;
int vis[10][10];
memset(vis,0,sizeof(vis));
int dir[4][2]={{0,1},{-1,0},{1,0},{0,-1}}; //方向数组 是8个数字啊!!!
Q.push(Sstart);
vis[Sstart.x][Sstart.y]=true;
while(!Q.empty())
{
Vnow=Q.front();
Q.pop();
for(int i=0;i<4;i++)
{
Vnext.x=Vnow.x+dir[i][0];
Vnext.y=Vnow.y+dir[i][1];
Vnext.time=Vnow.time-1;
Vnext.step=Vnow.step+1;
if(chage(Vnext,max_x,max_y))
{
//走到补给处
if(mp[Vnext.x][Vnext.y]==4&&Vnext.time>0)
{
Vnext.time=6;
mp[Vnext.x][Vnext.y]=0;
}
//走到出口出
if(Vnext.x==Eend.x&&Vnext.y==Eend.y&&Vnext.time>0)
{
return Vnext.step;
}
if(Vnext.time>1)
Q.push(Vnext); //第二个数入队列
}
}
}
return -1;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
memset(mp,0,sizeof(0));
// Start.x=Start.y=End.x=End.y;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>mp[i][j];
if(mp[i][j]==2) //记录开始结点的状态
{
Start.x=i;
Start.y=j;
Start.time=6;
Start.step=0;
}
else if(mp[i][j]==3) //记录结束结点的状态
{
End.x=i;
End.y=j;
}
}
}
cout<<bfs(Start,End,n,m)<<endl;
}
return 0;
}