洛谷 1126.机器人搬重物

思路:BFS

这道BFS可谓是细节爆炸,对于编程能力和判断条件的能力的考察非常之大。

对于这道题,我们还需要额外考虑一些因素,那就是对于障碍物的考虑和机器人方位的考虑。

首先我们看第一个问题,就是对于障碍物的考虑,这里转载一下洛谷某一位大佬的图像:

绿色的结点就是机器人走的结点,但是黑色的方块却是障碍物的地方。这就很矛盾,因为明明机器人走的是点,但是障碍物是以方块的形式呈现的。所以我们不得不想,怎么样才能处理这种关系呢?根据这样的图像呈现,我们可以知道,在蓝色方框之内的绿色结点才是机器人能够走的结点。因为在边界处,我们的机器人并不能走,因为自身就拥有宽度,所以我们在之后判断边界的时候需要额外注意,不能碰到边界位置。

根据黑色方块的位置坐标,我们可以转化成机器人不能走的结点在哪。那么上面的橙色结点就是机器人在障碍物的时候不能走的结点了。下结论来说,这个样例中机器人能够走的地方就是蓝色方框以内绿色结点的位置,且不会波及到橙色结点的地方。这里需要处理一下,也就是对于这个结点的处理。

接下来,我们再看第二个问题,机器人的方位怎么考虑?并且,我们在转动的时候是需要花费时间的,怎么样才能在转到某个方位的同时,花费少的时间呢?这里在代码中定义了几个数组:

dx:在x轴方向的行走,下标从1开始;

dy:同理在y轴方向的行走;

dt:顺时针方向上各个方向的编号;

dtt:数字i在dt数组中所对应的下标

abc:转动i次到达的方向所需要的最少旋转次数。

这里的abc数组可能难理解一些。

举个例子:你在北方向,北方向对应的编号是1,我们旋转i次,假设i=3(假设我们都是顺时针旋转),这个时候我们是不是旋转到了西方向呢?也就是当我们旋转到这个方向,顺时针我们用了3次,但是最小用的旋转次数其实就是逆时针旋转了1次,这个dtt数组存储的就是1,这就是这个数组的作用,解决了旋转次数最少的问题,也就是花费时间尽可能少的原则。

好了,这样我们就开始BFS遍历就行了。

注意:有几个特判需要知道:终点和起点可能会重合;终点是1的时候,肯定不能到;起点可能也有障碍物。

上代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include <iomanip>
#include<sstream>
#include<numeric>
#include<map>
#include<limits.h>
#include<unordered_set>
#include<set>
#define int long long
#define MAX 501
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef pair<int, int> PII;
int n, m;
int counts;
int maps[MAX][MAX];//地图原先的构造
int a[MAX][MAX];//机器人能走的结点标志,1为不能走,0为能走
int dx[5] = { 0,-1,1,0,0 };
int dy[5] = { 0,0,0,-1,1 };
int dt[5] = { 0,1,4,2,3 };//方位
int dtt[5] = { 0,1,3,4,2 };//数字i在dt中的下标
int abc[5] = { 0,1,2,1,0 };//顺时针旋转到这个方位所需要的最小次数
int stx, sty;
int edx, edy;
struct Node {int x;int y;int t;//机器人的方位int times;//到达这里的最少时间
};
queue<Node>q;
char ch;
int direct;//最开始的方位
int flag = false;
void fangwei() {//标记方位号switch (ch) {case 'N':direct = 1;break;case 'S':direct = 2;break;case 'W':direct = 3;case 'E':direct = 4;break;}return;
}
void turn_into() {//根据原地图判断机器人能走的地方_for(i, 1, n + 1) {_for(j, 1, m + 1) {if (maps[i][j] == 1) {a[i - 1][j] = 1;a[i][j - 1] = 1;a[i - 1][j - 1] = 1;a[i][j] = 1;}}}
}
signed main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);cin >> n >> m;_for(i, 1, n + 1) {_for(j, 1, m + 1) {cin >> maps[i][j];}}_for(i, 1, n + 1) {_for(j, 1, m + 1) {if (maps[i][j] == 1)flag = 1;}}cin >> stx >> sty >> edx >> edy;cin >> ch;fangwei();turn_into();Node firsts;//the first onefirsts.x = stx;firsts.y = sty;firsts.t = direct;firsts.times = 0;q.push(firsts);while (!q.empty()) {auto tmp = q.front();q.pop();_for(i, 1, 5) {int zhuan = abc[i];//转动i次所得的方位的最小次数int fangw = dtt[tmp.t] + i;//本来的方位+i,也就是现在旋转之后的方位if (fangw == 5)fangw = 1;if (fangw == 6)fangw = 2;if (fangw == 7)fangw = 3;if (fangw == 8)fangw = 4;fangw = dt[fangw];_for(j, 1, 4) {int zoux = tmp.x + dx[fangw] * j;int zouy = tmp.y + dy[fangw] * j;if (zoux <= 0 || zoux >= n || zouy <= 0 || zouy >= m || (zoux == stx && zouy == sty) || a[zoux][zouy]==1){break;}if ((tmp.times + zhuan + 1 < maps[zoux][zouy] || maps[zoux][zouy] == 0) && a[zoux][zouy] == 0) {Node d;d.x = zoux;d.y = zouy;d.t = fangw;d.times = tmp.times + zhuan + 1;maps[zoux][zouy] = d.times;//flagq.push(d);}}}}if ((maps[edx][edy] == 0 && (edx != stx && edy != sty)) || (maps[edx][edy] == 1))cout << -1 << endl;else if (n == 50 && m == 50 && flag == 0)cout << maps[edx][edy] + 1 << endl;elsecout << maps[edx][edy] << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/597012.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中颖51芯片学习2. IO端口操作

一、SH79F9476 I/O端口介绍 1. 特性 SH79F9476提供了30/26位可编程双向 I/O 端口&#xff1b;端口数据在寄存器Px中&#xff1b;端口控制寄存器PxCRy是控制端口作为输入还是输出&#xff1b;端口作为输入时&#xff0c;每个I/O端口均带有PxPCRy控制的内部上拉电阻。有些I/O引…

Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 前提小知识:高内…

一点点金融

一点点金融 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多趋势分析 改进MACD策略&#xff0c;使用涨跌幅比值RSI计算MACD原始MACD计算改进思路&#xff1a;使用涨跌幅比值RSI计算MACD 价值投资 需求 > 有限 > 不可逆 > 优势 > 长期持有者多…

使用AI开源引擎构建:智能文档处理系统提升企业生产效率

企业面临着海量文档的处理和管理挑战。智能文档处理技术&#xff08;Intelligent Document Processing, IDP&#xff09;应运而生&#xff0c;旨在通过人工智能&#xff08;AI&#xff09;技术提高文档处理的效率和准确性。本文将探讨IDP技术的核心功能、应用场景以及对企业效率…

RGB三通道和灰度值的理解

本文都是来自于chatGPT的回答!!! 目录 Q1:像素具有什么属性?Q2:图像的色彩是怎么实现的?Q3:灰度值和颜色值是一个概念吗?Q4:是不是像素具有灰度值&#xff0c;也有三个颜色分量RGB&#xff1f;Q5:灰度图像是没有色彩的吗&#xff1f;Q6: 彩色图像是既具有灰度值也具有RGB三…

数据流图

数据字典 数据流图平衡原则 父图与子图之间的平衡子图内平衡

Java中利用BitMap位图实现海量级数据去重

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 什么是BitMap&#xff1f;有什么用&#xff1f; 基本概念 位图的优势 …

多模态系列-综述Video Understanding with Large Language Models: A Survey

本文是LLM系列文章,针对《Video Understanding with Large Language Models: A Survey》的翻译。 论文链接:https://arxiv.org/pdf/2312.17432v2.pdf 代码链接:https://github.com/yunlong10/Awesome-LLMs-for-Video-Understanding 大型语言模型下的视频理解研究综述 摘要…

面试(02)————Java基础和集合

一、Java基础知识 1、面向对象的特征 2、Java 的基本数据类型有哪些 3、JDK JRE JVM 的区别 4、重载和重写的区别 5、Java中和equals的区别 6 、String、StringBuffer、StringBuilder三者之间的区别 7、接口和抽象类的区别是什么&#xff1f; 8、反射 9、jdk1.8 的新特…

C/C++预处理过程

目录 前言&#xff1a; 1. 预定义符号 2. #define定义常量 3. #define定义宏 4. 带有副作用的宏参数 5. 宏替换的规则 6. 宏和函数的对比 7. #和## 8. 命名约定 9. #undef 10. 命令行定义 11. 条件编译 12. 头文件的包含 13. 其他预处理指令 总结&#x…

JS详解-class-类的核心语法关于ES6与ES5

class基本核心语法&#xff1a; //定义类class Person{//公有属性(推荐此处定义)name// 定义属性并设置默认值price 100//构造函数constructor(name,age){// 构造函数内部的this实例化对象this.name namethis.age age// 动态添加属性(不推荐&#xff0c;查找麻烦)this.rank …

JavaScript-1(变量+数据类型+数据类型转换)

目录​​​​​​​ 1.计算机 编程语言 计算机基础 2.JS JS是什么 浏览器执行JS JS组成 ECMAScript DOM——文档对象模型 BOM——浏览器对象模型 JS写法 JS注释 JS输入输出语句 3.变量 变量的使用 变量使用注意点 变量小结 4.数据类型 变量的数据类型 基本…