题意大概:
机器人要从一个m*n(m和n的范围都在1到20的闭区间内)的网格的左上角(1,1)走到右下角(m,n)。网格中的一些格子是空地,用0表示,其它格子是障碍,用1表示。机器人每次可以往四个方向走一格,但不能连续地穿越k( [0,20] )个障碍,求最短路长度。起点和终点保证是空地。
思路:用bfs搜索即可,由于不能连续地穿越k个障碍,所以在原本的vis2维数组上面再添加1维,变成3维数组,表示穿越的墙的层数(障碍)。
参考博客:https://blog.csdn.net/u014004096/article/details/42920629
#include<bits/stdc++.h>
using namespace std;
int a[25][25];
int vis[25][25][25];
int dir[4][2]={
{-1,0},
{0,-1},{0,1},
{1,0}
};
int n,m,k;
typedef struct point{
int x,y,z,step;
}p;
int check(int x,int y){
if(x<0||x>=n||y<0||y>=m){
return false;
}
return true;
}
void bfs(int sx,int sy,int ex,int ey,int k){
p fir={sx,sy,0,0};
queue<p>q;
q.push(fir);
while(!q.empty()){
p cur=q.front();
q.pop();
if(cur.x==ex&&cur.y==ey){
printf("%d\n",cur.step);
return ;
}
for(int i=0;i<4;i++){
int tx=cur.x+dir[i][0];
int ty=cur.y+dir[i][1];
int tz=cur.z;
if(!check(tx,ty)){
continue;
}
if(a[tx][ty]==1){
tz++;
}else{
tz=0;
}
if(tz<=k&& check(tx,ty) && vis[tx][ty][tz]==0){
vis[tx][ty][tz]=1;
p next={tx,ty,tz,cur.step+1};
q.push(next);
}
}
}
printf("-1\n");
return ;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[i][j]);
}
}
bfs(0,0,n-1,m-1,k);
}
return 0;
}