题意 : 机器人要从一个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. [ASP.NET] [JS] GridView点击高亮当前选择行,并在点击另一行时恢复上一选择行背景颜色

    在ASP.NET中的gridview控件里面可以通过设定其OnRowDataBound事件来进行实现高亮当前行的操作 前端控件的设置: 只要设置好OnRowDataBound属性即可,会自动在.cs文 ...

  2. 2019JAVA第五次实验报告

    Java实验报告 班级 计科二班 学号 20188442 姓名 吴怡君 完成时间2019/10/11 评分等级 实验四 类的继承 实验目的 理解抽象类与接口的使用: 了解包的作用,掌握包的设计方法. ...

  3. 启用yarn的高可用

    选择高可用的主机,新的一台: 点运行结束后,会看到实例会多出一个备用的节点:

  4. PTA(Basic Level)1012.数字分类

    给定一系列正整数,请按要求对数字进行分类,并输出以下 5 个数字: A1 = 能被 5 整除的数字中所有偶数的和: A2 = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n1−n2+n ...

  5. Spring Security框架进阶、自定义登录

      1.Spring Security框架进阶 1.1 Spring Security简介 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安 ...

  6. Go语言的变量和常量(三)

    我想吐槽下网上的很多所谓的“零基础教程”,因为那根本不算零基础.就拿语言教程来说,一上来就说怎么定义变量的怎么算零基础呢?零基础应该是先告诉你啥叫变量. 所以我从不起零基础的标题.我这也不是教程,只是 ...

  7. 用ansible修改用户密码并给予挂载点

    --- - hosts: myjob gather_facts: false tasks: - name: chage user passwd user: name={{ item.name }} p ...

  8. 学会这些 pycharm 编程小技巧,编程效率提升 10 倍

    PyCharm 是一款非常强大的编写 python 代码的工具.掌握一些小技巧能成倍的提升写代码的效率,本篇介绍几个经常使用的小技巧. 一.分屏展示 当你想同时看到多个文件的时候: 1.右击标签页: ...

  9. Day2_数字类型_字符串类型_列表类型

    数字类型: 作用:年纪,等级,薪资,身份证号等: 10进制转为2进制,利用bin来执行. 10进制转为8进制,利用oct来执行. 10进制转为16进制,利用hex来执行. #整型age=10 prin ...

  10. JavaSE基础:泛型

    泛型 1.引入 情景模式描述,假设完成一个学生的成绩的情况: 整数: math=80,english=70 小数: math=85.6,englisth=77.8 字符串: math="66 ...