洛谷 1126.机器人搬重物

news2024/10/5 21:14:07

思路: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 one
    firsts.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;//flag
                    q.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;
    else
        cout << maps[edx][edy] << endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt Creator 界面

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、认识 Qt Creator 界面 1、总览 2、左边栏 3、代码编辑区 4、UI设计界面 5、构建区 一、认识 …

GitHub入门与实践

ISBN: 978-7-115-39409-5 作者&#xff1a;【日】大塚弘记 译者&#xff1a;支鹏浩、刘斌 页数&#xff1a;255页 阅读时间&#xff1a;2023-08-05 推荐指数&#xff1a;★★★★★ 好久之前读完的了&#xff0c;一直没有写笔记。 这本入门Git的书籍还是非常推荐的&#xff0c;…

【蓝桥杯】蓝桥杯算法复习(四)

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

深入浅出 -- 系统架构之Keepalived搭建双机热备

Keepalived重启脚本双机热备搭建 ①首先创建一个对应的目录并下载keepalived安装包&#xff08;提取码:s6aq&#xff09;到Linux中并解压&#xff1a; [rootlocalhost]# mkdir /soft/keepalived && cd /soft/keepalived [rootlocalhost]# wget https://www.keepalived.…

ROS2 采集虚拟仿真环境图像并发布

简介&#xff1a;ROS2功能的学习我们还是在基于OpenAI的gym虚拟仿真环境中来完成&#xff0c;gym虚拟仿真环境安装请参考另一篇教程&#xff0c;这里不再重复说明&#xff0c;接下来我们开始创建一个ROS2的功能节点&#xff0c;并发布虚拟仿真环境小车摄像头的图像&#xff0c;…

Android Studio 打开Local Changes界面

在编写代码的过程中&#xff0c;经常要回顾本地仓库做了那些修改。打开Local Changes界面&#xff0c;能做到一目了然&#xff0c;不用再去使用git命令查看。 File->Settings->Version control->Commit 把Use non-modal commit interface 选项 取消勾选 即可

20240403在ubuntu20.04下解压缩gz压缩包

20240403在ubuntu20.04下解压缩gz压缩包.txt 2024/4/3 15:17 缘起&#xff1a;使用友善之臂FriendlyElec的NanoPi NEO Core开发板 https://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO/zh#.E8.BF.90.E8.A1.8CFriendlyCore NanoPi NEO/zh http://wiki.friendlyelec.com/w…

Java基于微信小程序的校园外卖平台系统,附源码

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

蓝桥杯刷题 前缀和与差分-[NewOJ P1819]推箱子(C++)

题目描述 在一个高度为H的箱子前方&#xff0c;有一个长和高为N的障碍物。 障碍物的每一列存在一个连续的缺口&#xff0c;第i列的缺口从第l各单位到第h个单位&#xff08;从底部由0开始数&#xff09;。 现在请你清理出一条高度为H的通道&#xff0c;使得箱子可以直接推出去。…

同通俗易的理解 ADC

理解什么是ADC 文章目录 1、通俗理解什么是ADC 2、什么是ADC 3、ADC的采样率 4、采样位数 5、采样精度 ADC实际没有这么的简单&#xff0c;深入了解需要去学各种寄存器之间如何协作&#xff0c;信号如何走通。这些概念在后面会有讲解。 1、通俗理解…

UE4_X光效果设置_法线图影响透明度

UE4_X光效果设置_法线图影响透明度 2019-03-22 13:37 Exponentin 设置轮廓光扩散度 baseReflectFactionIn 设置内部黑色的亮度值。nromal&#xff0c;连接应用一张法线图&#xff0c;Lerp两色插值&#xff0c;给两个数值&#xff0c;制造一个渐变。 法线图影响透明度&#xf…

harbor机器断电之后服务正常,但是不能访问问题

1.进到harbor目录查看harbor服务是否正常 2.检查监听端口 3.检查防火墙 4.检查ip端口转发&#xff08;我这里刚刚开启&#xff0c;之前是关闭的。 1是开起&#xff0c;0是关闭&#xff09; 5.改为之后重启就可以正常访问了

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《提升光储充电站运行效率的多目标优化配置策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Redis的配置文件详解

单位&#xff1a;Redis配置对大小写不敏感&#xff01; 注意这里&#xff1a;任何写法都可&#xff0c;不区分大小写。 units are case insensitive so 1GB 1Gb 1gB are all the same.包含&#xff1a;搭建Redis集群时&#xff0c;可以使用includes包含其他配置文件网络&…

泰迪·南通师范大数据智能工作室挂牌签约仪式圆满结束

为促进毕业生高质量就业&#xff0c;拓宽就业渠道&#xff0c;加强校企合作&#xff0c;4月2日&#xff0c;泰迪智能科技股份有限公司上海分公司总经理彭艳昆一行来校出席南通师范高等专科学校“泰迪科技南通师范大数据智能工作室”签约揭牌仪式。学校党委副书记陈玉君、科技处…

瑞吉外卖实战学习--16、登录短信验证

登录短信验证 前言环境准备(根据mybatisPlus 规范实体类和接口)1、User实体类2、mapper文件3、service文件4、impl文件5、随机生成验证码的工具类6、发送验证码的工具类7、获取验证码和移动端登录前言 本项目gitee位置:gitee网址 本项目采用的技术是:springboot + mybatis…

c++虚函数表中的内存布局

c虚函数表中的内存布局 1.Class的内存分布2.其他修改Class中变量的方法3.通过虚函数表内存偏移调用虚函数4.继承状态下的虚函数表内存5.派生类函数中多出来的虚函数访问("基类指针指向子类对象") 1.Class的内存分布 #include <iostream>using namespace std;#…

ThreadLocal核心源码阅读

1. 概述 ThreadLocal为每个使用该变量的线程提供独立的变量副本&#xff0c;因此每一个线程都可以独立地改变自己的副本&#xff0c;而不会影响其他线程。 入门例子&#xff1a; public class ThreadLocalStudy {static ThreadLocal<String> stringThreadLocal new T…

Python爬取公众号封面图(零基础也能看懂)

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️感谢大家点赞&#x1f44d;&…

刷题之Leetcode209题(超级详细)

209.长度最小的子数组 力扣题目链接(opens new window)https://leetcode.cn/problems/minimum-size-subarray-sum/ 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条…