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 ncolumns). The rows are labeled from 1 to m. The columns are labeled from 1 to n. A cell (i, j)denotes the cell in row i and column j in the grid. At each step, the robot can only move from one cell to an adjacent cell, i.e. from (x, y) to (x + 1, y), (x, y + 1), (x - 1, y) or (x, y - 1). Some of the cells in the grid contain obstacles. In order to move to a cell containing obstacle, the robot has to switch to turbo mode. Therefore, the robot cannot move continuously to more than k cells containing obstacles.
Your task is to write a program to find the shortest path (with the minimum number of cells) from cell (1, 1) to cell (m, n). It is assumed that both these cells do not contain obstacles.
Input
The input consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 20. The following lines describe the data sets.
For each data set, the first line contains two positive integer numbers m and n separated by space(1≤m, n≤20). The second line contains an integer number k (0≤k≤20). The ith line of the next m lines contains n integer aij separated by space (i = 1, 2,..., m;j = 1, 2,..., n). The value ofaij is 1 if there is an obstacle on the cell (i, j), and is 0 otherwise.
Output
For each data set, if there exists a way for the robot to reach the cell (m, n), write in one line the integer number s, which is the number of moves the robot has to make; -1 otherwise.
Sample Input
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0
Simple Output
7
10
-1
题意
机器人从起点(0,0)走到(m,n),图中有障碍,机器人最多连续翻越k个障碍,求走到(m,n)的最短路径长度
题解1
一开始在二维上想怎么连续,而且已经访问过的点有可能再访问(本来的连续大),最后硬着头皮想了个蠢方法(if去判断)
代码1
#include<bits/stdc++.h>
using namespace std;
int Map[][],Cnt[][];//Map的值为连续越过的数量,Cnt的值为步数
int dx[]={,,,-};
int dy[]={,-,,};
int n,m,k;
struct Node
{
int x,y;
Node(int x=,int y=):x(x),y(y){}
};
int bfs()
{
queue<Node> qu;
Cnt[][]=;
qu.push(Node(,));
Node h,t;
while(!qu.empty())
{
h=qu.front();
qu.pop();
if(h.x==n&&h.y==m)return Cnt[n][m];
for(int i=;i<;i++)
{
t.x=h.x+dx[i];
t.y=h.y+dy[i];
if(t.x>=&&t.x<=n&&t.y>=&&t.y<=m)
{
//h表示当前,t表示下一个
if(Map[t.x][t.y]!=&&Map[h.x][h.y]!=)//当前和下一个!=0表示连续
if(Cnt[t.x][t.y]==-)//未访问过
Map[t.x][t.y]=Map[h.x][h.y]+;//下一个连续=当前连续+1
else if(Map[t.x][t.y]>Map[h.x][h.y]+)//若已访问过,如果下一个已经有的连续>当前+1
{
Map[t.x][t.y]=Map[h.x][h.y]+;//保证当前连续为最小连续,为了下一步走得更舒服
Cnt[t.x][t.y]=-;//标记未访问
}
if(Map[t.x][t.y]!=&&Map[h.x][h.y]==)//表示这是第一个连续
if(Cnt[t.x][t.y]==-)//未访问过
Map[t.x][t.y]=;//这个点为初始连续1
else if(Map[t.x][t.y]>)//若已访问过,如果下一个连续不是初始连续1,设为初始连续1
{
Map[t.x][t.y]=;//保证当前连续为最小连续,为了下一步走得更舒服
Cnt[t.x][t.y]=-;//标记未访问
}
if(Map[t.x][t.y]<=k&&Cnt[t.x][t.y]==-)//连续<=k,未访问
{
Cnt[t.x][t.y]=Cnt[h.x][h.y]+;
qu.push(t);
}
//上面处理的很蠢
}
}
}
return -;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
memset(Cnt,-,sizeof(Cnt));
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&Map[i][j]);
printf("%d\n",bfs());
}
return ;
}
题解2
后来发现可以用三维广搜去写,增加的第三维表示到这个点[X,Y]步数为STEP的情况
代码2
#include<bits/stdc++.h>
using namespace std;
int Map[][],Cnt[][],Vis[][][];//Vis[x][y][step]
int dx[]={,,,-};
int dy[]={,-,,};
int n,m,k;
struct Node
{
int x,y,step;//step为连续数
Node(int x=,int y=,int step=):x(x),y(y),step(step){}
};
int bfs()
{
queue<Node> qu;
Cnt[][]=;
Vis[][][]=;
qu.push(Node(,,));
Node h,t;
while(!qu.empty())
{
h=qu.front();qu.pop();
if(h.x==n&&h.y==m)return Cnt[n][m];
for(int i=;i<;i++)
{
t.x=h.x+dx[i];
t.y=h.y+dy[i];
t.step=h.step;
if(t.x>=&&t.x<=n&&t.y>=&&t.y<=m)
{
if(Map[t.x][t.y]==)t.step=h.step+;//墙,连续+1
else t.step=;//不是墙,连续=0
if(t.step<=k&&Vis[t.x][t.y][t.step]==)//连续<=k并且未访问
{
Vis[t.x][t.y][t.step]=;//标记访问
if(Cnt[t.x][t.y]==-)//未走到过(第一次走到的肯定是最小路径)
Cnt[t.x][t.y]=Cnt[h.x][h.y]+;
qu.push(t);
}
}
}
}
return -;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
memset(Cnt,-,sizeof(Cnt));
memset(Vis,,sizeof(Vis));
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&Map[i][j]);
printf("%d\n",bfs());
}
return ;
}
UVa 1600 Patrol Robot(三维广搜)的更多相关文章
- UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)
UVA 1600 Patrol Robot Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu ...
- UVa 1600 Patrol Robot (习题 6-5)
传送门: https://uva.onlinejudge.org/external/16/1600.pdf 多状态广搜 网上题解: 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰 ...
- Uva 1600 Patrol Robot (BFS 最短路)
这道题运用的知识点是求最短路的算法.一种方法是利用BFS来求最短路. 需要注意的是,我们要用一个三维数组来表示此状态是否访问过,而不是三维数组.因为相同的坐标可以通过不同的穿墙方式到达. #inclu ...
- UVa 1600 Patrol Robot (BFS最短路 && 略不一样的vis标记)
题意 : 机器人要从一个m * n 网格的左上角(1,1) 走到右下角(m, n).网格中的一些格子是空地(用0表示),其他格子是障碍(用1表示).机器人每次可以往4个方向走一格,但不能连续地穿越k( ...
- UVA 1600 Patrol Robot
带状态的bfs 用一个数(ks)来表示状态-当前连续穿越的障碍数: step表示当前走过的步数: visit数组也加一个状态: #include <iostream> #include & ...
- UVa 1600 Patrol Robot(BFS)
题意: 给定一个n*m的图, 有一个机器人需要从左上角(1,1)到右下角(n,m), 网格中一些格子是空地, 一些格子是障碍, 机器人每次能走4个方向, 但不能连续穿越k(0<= k <= ...
- UVa 1600 Patrol Robot【BFS】
题意:给出一个n*m的矩阵,1代表墙,0代表空地,不能连续k次穿过墙,求从起点到达终点的最短路的长度 给vis数组再加一维状态,表示当前还剩下的能够穿越的墙的次数,每次碰到墙,当前的k减去1,碰到0, ...
- UVA - 1600 Patrol Robot (巡逻机器人)(bfs)
题意:从(1,1)走到(m,n),最多能连续穿越k个障碍,求最短路. 分析:obstacle队列记录当前点所穿越的障碍数,如果小于k可继续穿越障碍,否则不能,bfs即可. #pragma commen ...
- PAT L3-004 肿瘤诊断(三维广搜)
在诊断肿瘤疾病时,计算肿瘤体积是很重要的一环.给定病灶扫描切片中标注出的疑似肿瘤区域,请你计算肿瘤的体积. 输入格式: 输入第一行给出4个正整数:M.N.L.T,其中M和N是每张切片的尺寸(即每张切片 ...
随机推荐
- 机器学习进阶-案例实战-答题卡识别判 1.cv2.getPerspectiveTransform(获得投射变化后的H矩阵) 2.cv2.warpPerspective(H获得变化后的图像) 3.cv2.approxPolyDP(近似轮廓) 4.cv2.threshold(二值变化) 7.cv2.countNonezeros(非零像素点个数)6.cv2.bitwise_and(与判断)
1.H = cv2.getPerspectiveTransform(rect, transform_axes) 获得投射变化后的H矩阵 参数说明:rect表示原始的位置左上,右上,右下,左下, tra ...
- C# 如何利用反射,将字符串转化为类名并调用类中方法
首先,先随便创建一个测试类 <span style="font-family:Microsoft YaHei;font-size:18px;">public class ...
- printf 输出% 和 \
在小白第一章后面1.5.3中有仨题: 1 试着把%d中的两个字符(百分号和小写字母d)输出到屏幕. 2 试着把\n中的两个字符(反斜线和小写字母n)输出到屏幕. 3 像 1.2这样需要“特殊方法”才能 ...
- 微信、陌陌等著名IM软件设计架构详解(转)
对微信.陌陌等进行了分析,发出来分享一下(时间有些久了) 电量:对于移动设备最大的瓶颈就是电量了.因为用户不可能随时携带电源,充电宝.所以必须考虑到电量问题.那就要检查我们工程是不是有后台运行,心跳包 ...
- linux mce的一些相关内容和用户态监控的设计方法
之所以想起写一点关于mce的东西,倒不是因为遇到mce的异常了,之前遇到过很多mce的异常,内存居多,但没有好好记录下来,写这个是因为参加2018 clk南京会议的一点想法. void __init ...
- 1.13.Mark1
[经济学人]双语阅读:律师事务所 标价更高 收益更少 Business 商业报道 Law firms 律师事务所 Charging more, getting less 标价更高,收益更少 L ...
- requirejs源码分析
- 使用pickle进行存储变量
有时候我们需要把我们的变量内容存下来,这时我们就可以用pickle来操作. 存储操作如下所示: #!/usr/bin/python # -*- coding:utf-8 -*- import pick ...
- Applese涂颜色-欧拉降幂公式
链接:https://ac.nowcoder.com/acm/contest/330/E来源:牛客网 题目描述 精通程序设计的 Applese 叕写了一个游戏. 在这个游戏中,有一个 n 行 m 列的 ...
- 服务器安装pip
1. wget --no-check-certificate https://pypi.python.org/packages/source/s/setuptools/setuptools-19.6. ...