题意 : 机器人要从一个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. 在CentOS 8 Linux中安装使用Cockpit服务器管理软件

    在本文中,我们将帮助您在CentOS 8服务器中安装Cockpit Web 控制台,以管理和监视本地系统以及网络环境中的Linux服务器.您还将学习如何将远程Linux主机添加到Cockpit并在Ce ...

  2. C语言作业08

    问题 答案 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://i.cnblogs.com/EditPosts.aspx?opt=1 我在这个课程的目标是 在学好C语言编程的 ...

  3. [转帖]Chrome 错误代码:ERR_UNSAFE_PORT

    Chrome 错误代码:ERR_UNSAFE_PORT 2018年07月18日 09:07:50 孤舟听雨 阅读数 182 https://blog.csdn.net/u013043762/artic ...

  4. js知识点——1

    onload 事件会在页面或图像加载完成后立即发生. document.write("内容")将在加载页面时输出 内容可以是什么,可以是一个标签,它输出的文件不能自动换行: < ...

  5. python网络爬虫(1)静态网页抓取

    获取响应内容: import requests r=requests.get('http://www.santostang.com/') print(r.encoding) print(r.statu ...

  6. MySql 5.7关键字和保留字-附表

    现在使用navicat图形界面或者Hibernate做映射生成表的时候,渐渐的会忽视掉关键字这个问题,而后续也会不断的产生错误提示,一遍遍的查询代码无果,甚至开始怀疑人生,但是其实很多情况下只是使用了 ...

  7. jstat命令使用

    jstat命令使用 jstat是JDK自带的一个轻量级小工具,全称"Java Virtual Machine statistics monitoring tool",它位于java ...

  8. 在easyui中解决使west和center为1:1,并且拖动窗口时能够自适应变化

    <script type="text/javascript"> // 解决页面两个grid的布局问题 $(function(){// 在页面加载完毕后 //consol ...

  9. C++质因数分解

    // CPP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<cs ...

  10. python基础练习题6

    01:求1+2!+3!+....+20!的和 s=0 t=1 for n in range(1,21): t*=n s+=t print('1!+2!+3!+.....+20!=%d'%s) 02:利 ...