此题属单源最短路问题,适合用广度优先搜索求解。
深度优先搜索一般用递归的方法实现,而广度优先搜索一般用队列的方式实现。
首先将开始点压入队列,然后执行这样一个过程:队首点出队列,将与其相邻的点压入队列。
注意:遇到时光机,重置时间,要把此点变为墙,因为时光机仅需要用一次,这样还可以避免在两个时光机之间一直走循环结束不了的问题。
#include<iostream>
#include<queue>
using namespace std;
typedef struct loc
{
int x;
int y;
int time;//记录时间
int step; //记录步数
}loc;
int map[100][100];
int vec[2][4]={{0,1,0,-1},
{1,0,-1,0}};//四个方向
int bfs(int sx,int sy,int N,int M)
{
queue<loc>a;
loc start;
start.x=sx;
start.y=sy;
start.step=0;
start.time=0;
a.push(start);
while(1)
{
loc box=a.front();//将要弹出的点记录下来
a.pop();//注意先将点弹出来
for(int i=0;i<4;i++)//循环4次,考虑弹出点的周围4个点
{
loc p;
p.x=box.x+vec[0][i];
p.y=box.y+vec[1][i];
if(p.x<0||p.x>N-1||p.y<0||p.y>M-1){continue;}//如果这个点超出了地图,考虑下个点
p.time=box.time+1;
p.step=box.step+1;
if(p.time==6){continue;}//这条路径超时了
if(map[p.x][p.y]==3)return p.step;//正解,直接返回步数
if(!map[p.x][p.y]){continue;}//这个点值为0,也就是墙,考虑下个点
if(map[p.x][p.y]==4)
{
p.time=0;
map[p.x][p.y]=0;
}
a.push(p);
}
if(a.empty()==1)return -1;
}
}
int main()
{
int qwert,N,M,sx,sy;//数据组数 行数 列数 开始位置(sx,sy)
cin>>qwert;
while(qwert--)
{
cin>>N>>M;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
{
sx=i;sy=j;
}
}
}
cout<<bfs(sx,sy,N,M)<<'\n';
}
return 0;
}
#include<queue>
using namespace std;
typedef struct loc
{
int x;
int y;
int time;//记录时间
int step; //记录步数
}loc;
int map[100][100];
int vec[2][4]={{0,1,0,-1},
{1,0,-1,0}};//四个方向
int bfs(int sx,int sy,int N,int M)
{
queue<loc>a;
loc start;
start.x=sx;
start.y=sy;
start.step=0;
start.time=0;
a.push(start);
while(1)
{
loc box=a.front();//将要弹出的点记录下来
a.pop();//注意先将点弹出来
for(int i=0;i<4;i++)//循环4次,考虑弹出点的周围4个点
{
loc p;
p.x=box.x+vec[0][i];
p.y=box.y+vec[1][i];
if(p.x<0||p.x>N-1||p.y<0||p.y>M-1){continue;}//如果这个点超出了地图,考虑下个点
p.time=box.time+1;
p.step=box.step+1;
if(p.time==6){continue;}//这条路径超时了
if(map[p.x][p.y]==3)return p.step;//正解,直接返回步数
if(!map[p.x][p.y]){continue;}//这个点值为0,也就是墙,考虑下个点
if(map[p.x][p.y]==4)
{
p.time=0;
map[p.x][p.y]=0;
}
a.push(p);
}
if(a.empty()==1)return -1;
}
}
int main()
{
int qwert,N,M,sx,sy;//数据组数 行数 列数 开始位置(sx,sy)
cin>>qwert;
while(qwert--)
{
cin>>N>>M;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
{
sx=i;sy=j;
}
}
}
cout<<bfs(sx,sy,N,M)<<'\n';
}
return 0;
}