Problem

题目概括

  • $n \times m $ 的网格,有些格子是障碍格。\(0\) 无障碍,\(1\) 有障碍。机器人有体积,总是在格点上

  • 有5种操作:

    • 向前移动 \(1/2/3\) 步
    • 左转 \(/\) 右转
  • 每次操作需要 \(1\) 秒。

  • 求从 \(x_1,y_1\) 到 \(x_2,y_2\) 点的最短路。

  • 机器人有一个初始方向 $ E / S / W / N$ (东南西北)。

思路

  1. 考察算法:BFS求最短路。
  2. 实现过程 \(\&\) 注意点:
      1. 障碍是在格子上的,需要将周围 \(4\) 个点标记为障碍。
      1. 本题下标从 \(0\) 开始
      1. 由于机器人有体积,所以可走的范围只有 \((1,1) ~ (n - 1,m - 1)\) !
      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 机器人搬重物 题解的更多相关文章

  1. luogu P1126 机器人搬重物 题解

    luogu P1126 机器人搬重物 题解 题目描述 机器人移动学会(\(RMI\))现在正尝试用机器人搬运物品.机器人的形状是一个直径\(1.6\)米的球.在试验阶段,机器人被用于在一个储藏室中搬运 ...

  2. P1126 机器人搬重物

    P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...

  3. 洛谷——P1126 机器人搬重物

    P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...

  4. 洛谷P1126 机器人搬重物

    洛谷1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格, ...

  5. 洛谷P1126 机器人搬重物【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1126 题意: 给定一个n*m的方格,机器人推着直径是1.6的球在格子的线上运动. 每一秒钟可以向左转,向右转 ...

  6. 洛谷P1126机器人搬重物[BFS]

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...

  7. 洛谷 P1126 机器人搬重物

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径 $1.6 米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个 N×MN \times MN×M ...

  8. luogu P1126 机器人搬重物

    题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有些格子为不可移动的障碍.机 ...

  9. 洛谷 P1126 机器人搬重物 (BFS)

    题目链接:https://www.luogu.org/problemnew/show/P1126 吐槽:这题很阴险 一开始没把格子图转化成点图:30分 转化成点图,发现样例过不去,原来每步要判断vis ...

  10. 洛谷—— P1126 机器人搬重物

    https://www.luogu.org/problem/show?pid=1126 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机 ...

随机推荐

  1. CentOS 8搭建Docker镜像私有仓库-registry

    目录 简介 安装Docker 添加docker yum源 安装docker 确保网络模块开机自动加载 使桥接流量对iptables可见 配置docker 验证docker是否正常 添加用户到docke ...

  2. 处理.git文件夹过大出现臃肿问题-filter-branch和BFG工具

    Git开发手册 git一些不常用的命令记不住,可以查看git开发手册(https://m.php.cn/manual/view/34957.html) 1..git/objects/pack 文件过大 ...

  3. vue和servlet 前后端分离 (复习)

    一.vue复习 1.vue的使用步骤: (1)导入vue.js (2)创建除body以外最大的div标签,给定id值 (3)创建vue对象 new Vue({ el:"#app", ...

  4. 【EF Core】主从实体关系与常见实体关系的区别

    上次老周扯了有关主.从实体的话题,本篇咱们再挖一下,主.从实体之间建立的关系,跟咱们常用的一对一.一对多这些关系之间有什么不同. 先看看咱们从学习数据库开始就特熟悉的常用关系--多对多.一对一.一对多 ...

  5. 【技术积累】Vue.js中的组件库【一】

    Vue组件库是什么 Vue中的组件库是一组预先构建好的可重用组件,用于加速开发过程并提高代码的可维护性.组件库通常包含一系列常用的UI组件,如按钮.输入框.下拉菜单等,以及一些功能性组件,如模态框.轮 ...

  6. 2021-11-29 Wpf的ViewModel和xaml绑定

    ViewModel代码 public class MainViewModel { MainWindow _mainWindow; public MainViewModel(MainWindow mai ...

  7. python将两个列表组合成元组

    point_x = [A_x, B_x, C_x, D_x] point_y = [A_y, B_y, C_y, D_y] points_tulpe = list(zip(point_x, point ...

  8. Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-4_w0c665/PyQt5/

    错误: 解决方式:输入一下命令 1 pip3 install --upgrade setuptools 2 python3 -m pip install --upgrade pip 输入命令: 1 p ...

  9. [python]使用diagrams绘制架构图

    简介 diagrams是python的一个第三方库,用于实现使用代码绘制架构图. 安装 依赖于 Graphviz,安装diagrams之前需要先安装 Graphviz(下载压缩包后,将bin目录添加到 ...

  10. lazarus、delphi文件Http下载断点续传的实现

    下载大文件时,断点续传是很有必要的,特别是网速度慢且不稳定的情况下,很难保证不出意外,一旦意外中断,又要从头下载,会很让人抓狂.断点续传就能很好解决意外中断情况,再次下载时不需要从头下载,从上次中断处 ...