题意 : 机器人要从一个m * n 网格的左上角(1,1) 走到右下角(m, n)。网格中的一些格子是空地(用0表示),其他格子是障碍(用1表示)。机器人每次可以往4个方向走一格,但不能连续地穿越k(0≤k≤20)个障碍,求最短路长度。起点和终点保证是空地。

分析 : 很明显的BFS最短路,但是这里有坑呀!如果只是单纯使用二维数组去标记是否已经访问过改点是错误的做法,走到该点的机器人因为有穿越障碍物的步数限制,所以可能有些 略绕但是行得通的路 就会被二维数组这种标记方式把路给封死,比如下面这个例子,假设BFS机器人的走位是先右后左,并且k = 3,如果采用二维标记则会出错

0 1 1 1 1

0 1 1 1 0

为什么会有这种情况呢?因为在普通BFS中能走的都是通路,如果当前点再去走已经被标记的点必然不是最优,而现在对于机器人而言,又有一个可跨越障碍的步数这个限制,那么走到某一个点当然是机器人还能跨越障碍物的步数越多越好,也就是说对于同一个点只要没有走已经走过的点必然不是最优这种条件的话,就要慎重考虑使用普通的BFS解法了!现在回到这个题,其实解决的办法就是给vis再增加一个维度,表示当前机器人是跨越了多少个障碍物来到这里的这个状态即可。不过实际上根据刚刚的分析,我们可以做个小小的优化,就是如果当前机器人到达这个点还能跨越障碍物的步数少于之前已经来过这里的机器人的话,那必然不是最优,无需入队!

#include<bits/stdc++.h>
using namespace std;
int n, m, k, ans;
struct robot
{
    robot(int r, int c, int C, int s):row(r), col(c), cross(C), step(s){};
    int row, col, cross, step;
};
, -, ,  };
,  , , -};
][][], G[][];
][];//记录当前机器人还剩的跨越障碍物的机会
 || c<); }
inline void BFS()
{
    queue<robot> q;
    memset(vis, false, sizeof(vis));
    memset(Chance, 0x3f, sizeof(Chance));
    q.push(robot(,,,));
    vis[][][] = true;
    while(!q.empty()){
        robot tmp = q.front();
        q.pop();
        if(tmp.row==n && tmp.col==m){
            ans = tmp.step;
            break;
        }
        ; i<; i++){
            int row = tmp.row + dr[i];
            int col = tmp.col + dc[i];
            int C = tmp.cross;
            ;
            ;
            if( !bound(row, col) && C <= k && !vis[row][col][C] && C < Chance[row][col]){//当前机器人到达这个点还能跨越更多的障碍物
                vis[row][col][C] = true;
                Chance[row][col] = C;
                q.push(robot(row, col, C, tmp.step+));
            }
        }
    }
}
int main(void)
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int nCase;
    scanf("%d", &nCase);
    while(nCase--){
        scanf("%d %d %d", &n, &m, &k);
        ans = -;
        memset(G, false, sizeof(G));
        ; i<=n; i++){
            ; j<=m; j++){
                int BOOL;
                scanf("%d", &BOOL);
                if(!BOOL) G[i][j] = true;
            }
        }
        BFS();
        printf("%d\n", ans);
    }
    ;
}

瞎 : 已经碰见过两次这种可以跨障碍物的BFS最短路题了,要时刻清楚vis标记的是状态,根据状态有无更优来舍取是否入队操作。

UVa 1600 Patrol Robot (BFS最短路 && 略不一样的vis标记)的更多相关文章

  1. Uva 1600 Patrol Robot (BFS 最短路)

    这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #inclu ...

  2. UVa 1600 Patrol Robot(BFS)

    题意: 给定一个n*m的图, 有一个机器人需要从左上角(1,1)到右下角(n,m), 网格中一些格子是空地, 一些格子是障碍, 机器人每次能走4个方向, 但不能连续穿越k(0<= k <= ...

  3. UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)

    UVA 1600 Patrol Robot   Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu   ...

  4. UVa 1600 Patrol Robot【BFS】

    题意:给出一个n*m的矩阵,1代表墙,0代表空地,不能连续k次穿过墙,求从起点到达终点的最短路的长度 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰到墙,当前的k减去1,碰到0, ...

  5. UVA - 1600 Patrol Robot (巡逻机器人)(bfs)

    题意:从(1,1)走到(m,n),最多能连续穿越k个障碍,求最短路. 分析:obstacle队列记录当前点所穿越的障碍数,如果小于k可继续穿越障碍,否则不能,bfs即可. #pragma commen ...

  6. UVa 1600 Patrol Robot (习题 6-5)

    传送门: https://uva.onlinejudge.org/external/16/1600.pdf 多状态广搜 网上题解: 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰 ...

  7. UVa 1600 Patrol Robot(三维广搜)

    A robot has to patrol around a rectangular area which is in a form of m x n grid (m rows and ncolumn ...

  8. UVA 1600 Patrol Robot

    带状态的bfs 用一个数(ks)来表示状态-当前连续穿越的障碍数: step表示当前走过的步数: visit数组也加一个状态: #include <iostream> #include & ...

  9. 【UVa】1600 Patrol Robot(dfs)

    题目 题目     分析 bfs可以搞,但是我还是喜欢dfs,要记忆化不然会T     代码 #include <cstdio> #include <cstring> #inc ...

随机推荐

  1. win10序列号 2019年10月测试

    win10序列号 N3415-266GF-AH13H-WA3UE-5HBT4 win10序列号 NPK3G-4Q81M-X4A61-D553L-NV68D win10序列号 N617H-84K11-6 ...

  2. mysql的最左索引匹配原则

    最近复习数据库,主要看的是mysql.很多东西忘得一干二净.看到某乎上有个答案非常给力,就记录一下,以后方便查看. 链接:https://www.zhihu.com/question/36996520 ...

  3. Java基础(四)

    概述 常用快捷键 数组 概述 数组是一种引用类型.变量只可以存放一个数据,数组则可以存放多个类型统一的数据,可以存放基本类型,也可以存放引用类型. 如果需要存储的数据很多,那么定义多个变量很麻烦: I ...

  4. GPIB、USB、PCI、PCI Express和以太网/LAN/LXI

    GPIB 我们研究的第一个总线是IEEE 488总线,较为熟悉的称谓是GPIB(通用接口总线).GPIB是一种在业界已经得到证明的专为仪器控制应用设计的总线.GPIB在过去30年来一直是鲁棒的.可靠的 ...

  5. Centos7安装Beanstalkd

    安装 //安装 yum -y install beanstalkd --enablerepo=epel //查看版本 beanstalkd -v //启动 -b断电重启会恢复 /usr/bin/bea ...

  6. Flask运行时指定端口

    在项目入口文件server.php中,有如下代码 if __name__ == '__main__': app.run(debug=True,port=8000) 但是在进入虚拟机中运行 flask ...

  7. openCV 二 图像处理

    官网:https://docs.opencv.org/3.2.0/df/d9d/tutorial_py_colorspaces.html 改变颜色空间 本教程颜色空间转换:BGR ↔ Gray and ...

  8. Fliter设置字符编码,解决中文问题

    class EncodingFilter implements FileFilter{ private String encoding; @Override public boolean accept ...

  9. vue项目进行时,script标签中,methods事件中函数使用的async/await

    用 async/await 来处理异步 await关键字只能放到async函数里面,通过await得到就是Promise返回的内容:当然也能通过then()去获取,若通过then()获取了则就无Pro ...

  10. 关于Vue父子组件传值(复杂数据类型的值)的细节点

    vue 父子组件传值是很常见的,多数情况下都是父传递给子的值是基础数据类型,如string,number,boolean, 当父组件值被修改时,子组件能够实时的作出改变. 如果父子传值的类型是复杂数据 ...