P1126 机器人搬重物 题解
Problem
题目概括
$n \times m $ 的网格,有些格子是障碍格。\(0\) 无障碍,\(1\) 有障碍。机器人有体积,总是在格点上。
有5种操作:
- 向前移动 \(1/2/3\) 步
- 左转 \(/\) 右转
每次操作需要 \(1\) 秒。
求从 \(x_1,y_1\) 到 \(x_2,y_2\) 点的最短路。
机器人有一个初始方向 $ E / S / W / N$ (东南西北)。
思路
- 考察算法:BFS求最短路。
- 实现过程 \(\&\) 注意点:
- 障碍是在格子上的,需要将周围 \(4\) 个点标记为障碍。
- 本题下标从 \(0\) 开始。
- 由于机器人有体积,所以可走的范围只有 \((1,1) ~ (n - 1,m - 1)\) !
- 在一次性走 \(2,3\) 步的时候,一定要判断 \(a\) 数组中路上的每一个点是否为 \(0\)。不然会出现 \(“\) 穿墙 \(”\) 的情况。
定义一个 queue<node> q; ,然后 \(node\) 里面有 \(4\) 个信息:\(x,y,k,step\)。 \(k\) 代表当前的方向在方向数组中的下标,\(step\) 表示花了几秒 \((\)走了几步\()\)。
然后本题 \(bool\) 类型的 \(vis\) 数组可以开成三维的。
\(vis[x][y][k]\) 代表 \(x,y\) 点的 \(k\) 方向已经被走过了。
然后 \(BFS\) ,就可以 \(AC\) 了~
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 60;
struct node {
int X, Y, K, stp;
};
queue<node> q;
// 方向数组
int fx[5] = {0, 1, 0, -1};
int fy[5] = {1, 0, -1, 0};
int n, m;
int a[N][N], sx, sy, ex, ey, k, xx;
bool vis[N][N][5];
char c;
map<char, int> mp; // 映射四个方向对应方向数组的下标(0-3)
// 将障碍格四周的点标记为1
void fun(int x, int y) {
a[x][y] = a[x - 1][y - 1] = a[x - 1][y] = a[x][y - 1] = 1;
}
// 检验坐标是否合法
bool check(int x, int y) { return x > 0 && x < n && y > 0 && y < m; }
// 左转
int TurnLeft(int tmpk) { return (tmpk + 3) % 4; }
// 右转
int TurnRight(int tmpk) { return (tmpk + 5) % 4; }
int bfs() {
// 初始化
q.push((node) {sx, sy, k, 0});
vis[sx][sy][k] = true;
while (!q.empty()) {
int x = q.front().X, y = q.front().Y, tk = q.front().K, step = q.front().stp;
q.pop();
// 到达终点
if (x == ex && y == ey) return step;
// 左转 & 右转
if (!vis[x][y][TurnLeft(tk)] && !a[x][y]) {
q.push((node) {x, y, TurnLeft(tk), step + 1});
vis[x][y][TurnLeft(tk)] = true;
}
if (!vis[x][y][TurnRight(tk)] && !a[x][y]) {
q.push((node){x, y, TurnRight(tk), step + 1});
vis[x][y][TurnRight(tk)] = true;
}
int oi = x + fx[tk], oj = y + fy[tk];
int oi_2 = x + 2 * fx[tk], oj_2 = y + 2 * fy[tk];
int oi_3 = x + 3 * fx[tk], oj_3 = y + 3 * fy[tk];
// 走 1/2/3 步
if (!vis[oi][oj][tk] && !a[oi][oj] && check(oi, oj)) {
q.push((node){oi, oj, tk, step + 1});
vis[oi][oj][tk] = true;
}
if (check(oi_2, oj_2) && !vis[oi_2][oj_2][tk] && !a[oi][oj] && !a[oi_2][oj_2]) {
q.push((node){oi_2, oj_2, tk, step + 1});
vis[oi_2][oj_2][tk] = true;
}
if (check(oi_3, oj_3) && !vis[oi_3][oj_3][tk] && !a[oi][oj] && !a[oi_2][oj_2] && !a[oi_3][oj_3]) {
q.push((node){oi_3, oj_3, tk, step + 1});
vis[oi_3][oj_3][tk] = true;
}
}
return -1; // 走不到
}
int main() {
mp['E'] = 0, mp['S'] = 1, mp['W'] = 2, mp['N'] = 3; // 初始化方向
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
a[i][0] = a[0][i] = a[i][m] = a[n][i] = 1;
for (int j = 1; j <= m; j++) {
scanf("%d", &xx);
if (xx == 1) fun(i, j); // 障碍点四周的点都标记为1
}
}
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
cin >> c;
k = mp[c]; // 映射方向
printf("%d", bfs());
return 0;
}
P1126 机器人搬重物 题解的更多相关文章
- luogu P1126 机器人搬重物 题解
luogu P1126 机器人搬重物 题解 题目描述 机器人移动学会(\(RMI\))现在正尝试用机器人搬运物品.机器人的形状是一个直径\(1.6\)米的球.在试验阶段,机器人被用于在一个储藏室中搬运 ...
- P1126 机器人搬重物
P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...
- 洛谷——P1126 机器人搬重物
P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...
- 洛谷P1126 机器人搬重物
洛谷1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格, ...
- 洛谷P1126 机器人搬重物【bfs】
题目链接:https://www.luogu.org/problemnew/show/P1126 题意: 给定一个n*m的方格,机器人推着直径是1.6的球在格子的线上运动. 每一秒钟可以向左转,向右转 ...
- 洛谷P1126机器人搬重物[BFS]
题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...
- 洛谷 P1126 机器人搬重物
题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径 $1.6 米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个 N×MN \times MN×M ...
- luogu P1126 机器人搬重物
题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...
- 洛谷 P1126 机器人搬重物 (BFS)
题目链接:https://www.luogu.org/problemnew/show/P1126 吐槽:这题很阴险 一开始没把格子图转化成点图:30分 转化成点图,发现样例过不去,原来每步要判断vis ...
- 洛谷—— P1126 机器人搬重物
https://www.luogu.org/problem/show?pid=1126 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机 ...
随机推荐
- Typora markdown 满屏显示,去除两边的留白
Typora 宽度在CSS样式文件中有个 max-width 值,现在的显示器分辨率比较高,会导致编辑器两边留白比较多 导致文档编辑时,高分辨率的显示器,得不到充分利用 解决方案 修改源码编辑器样式 ...
- Cookie相关基础
1) 创建Cookie对象, public Cookie(java.lang.String name, java.lang.String value) 参数1:表示cookie名称 参数2:表示coo ...
- [爬虫]2.2.1 使用Selenium库模拟浏览器操作
Selenium是一个非常强大的工具,用于自动化Web浏览器的操作.它可以模拟真实用户的行为,如点击按钮,填写表单,滚动页面等.由于Selenium可以直接与浏览器交互,所以它可以处理那些需要Java ...
- 我通过 tensorflow 预测了博客的粉丝数
前言: 由于最近接触了 tensorflow.js,出于试一下的心态,想通过线性回归预测一下博客的粉丝走向和数量,结果翻车了.虽然场景用错地方,但是整个实战方法用在身高体重等方面的预测还是有可行性,所 ...
- sqli笔记
MySQL数据库自带的数据库information_schema 里面有三个比较重要的表 SCHEMATA .TABLES . COLUMNS 保存数据库所有的数据库名 表名 字段名 SCHEM ...
- centos转移mysql的数据存储目录
前言 centos7使用yum安装mysql的时候,没修改存储位置,/var也没单独挂载,导致长时间运行后根目录空间不足.现需要将数据转移到大分区的/home,操作步骤如下. 步骤 创建新目录 mkd ...
- 利用pytorch自定义CNN网络(三):构建CNN模型
本文是利用pytorch自定义CNN网络系列的第三篇,主要介绍如何构建一个CNN网络,关于本系列的全文见这里. 笔者的运行设备与软件:CPU (AMD Ryzen 5 4600U) + pytorch ...
- opencv-python 车牌检测和识别
首先利用级联分类器把车牌位置找到取出来,然后用ocr进行车牌识别. 1 OCR之Tesseract安装 Tesseract安装可以参考这个链接: https://blog.csdn.net/m0_53 ...
- 操作过滤器—MVC中使用操作过滤器实现JWT权限认证
前言 上一篇文章分享了授权过滤器实现JWT进行鉴权,文章链接:授权过滤器-MVC中使用授权过滤器实现JWT权限认证,接下来将用操作过滤器实现昨天的JWT鉴权. 一.什么是操作过滤器? 与授权过滤器 ...
- 【Unity3D】平面光罩特效
1 前言 屏幕深度和法线纹理简介中对深度和法线纹理的来源.使用及推导过程进行了讲解,激光雷达特效中讲述了一种重构屏幕像素点世界坐标的方法,本文将沿用激光雷达特效中重构像素点世界坐标的方法,实现平面 ...