Uva1600(巡逻机器人)-(三维BFS)

传送门

题意大概:

机器人要从一个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;
}

猜你喜欢

转载自blog.csdn.net/z_sea/article/details/80710269
今日推荐