扫地机器人(蓝桥杯)

文章目录

扫地机器人

题目描述

小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所 示。

走廊内部署了 K 台扫地机器人,其中第 i 台在第 A~i~ 个方格区域中。已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净

请你编写一个程序,计算每台机器人的清扫路线,使得

  1. 它们最终都返回出发方格,

  2. 每个方格区域都至少被清扫一遍,

  3. 从机器人开始行动到最后一台机器人归位花费的时间最少。

注意多台机器人可以同时清扫同一方块区域,它们不会互相影响

输出最少花费的时间。在上图所示的例子中,最少花费时间是 6。第一台路线:2-1-2-3-4-3-2,清 扫了 1、2、3、4 号区域。第二台路线 5-6-7-6-5,清扫了 5、6、7。第三台路线 10-9-8-9-10,清扫了 8、9 和 10。

输入描述

第一行包含两个整数 N 和 K。

接下来 K 行,每行一个整数 Ai。

输出描述

输出一个整数表示答案

样例输入

10 3
5
2
10

样例输出

6

解题思路

首先这题需要找到最少花费时间,那么我们先二分机器人的扫地范围,最小为0,最大为n,一旦所有机器人能扫完全程,说明该值是符合条件的,然后二分缩小范围,直到找出最小的值,刚好所有机器人能够扫完全程。

check函数的实现:

  • 首先我们需要明确,mid是机器人的扫地步数,如果mid为1,那么机器人就扫机器人当前的格子。
  • 然后开始贪心思路:我们尽可能让机器人先扫完自己右边的,然后有多余的步数,再扫自己左边的。
  • 情况一:如果a[i]-x>s,就说明机器人扫不完自己右边的格子,直接返回false
  • 情况二:如果前一个机器人往右多扫了几格,S应该更新为s = a[i] + x - 1
  • 如果上述两种情况都不属于,将s向前推进x个方格s += x
  • 最后,如果S大于等于地图范围n,返回true,否则说明机器人没走完全程,返回false

二分+贪心

这段代码是一个用于解决扫地机器人问题的C++程序。程序的目的是通过编写一个算法,使得多台扫地机器人能够高效地清扫一个由N个方格区域组成的走廊,并最终返回各自的出发点。下面是对代码的详细注释:

cpp 复制代码
#include<bits/stdc++.h> // 引入C++标准库的头文件,bits/stdc++.h是一个非标准的宏定义,包含了常用的头文件
using namespace std; // 使用标准命名空间,简化标准库中的类和函数的引用

// 定义全局变量
int n, k; // n表示走廊的方格数,k表示扫地机器人的数量
int a[100010]; // 数组a用于存储k台扫地机器人的初始位置

// check函数用于判断在给定的清扫时间x下,是否所有方格都被清扫过
bool check(int x) {
    int s = 0; // s表示当前已清扫的方格区域的右边界
    for(int i = 0; i < k; i++) { // 遍历所有的扫地机器人
        if(a[i] - x > s) return false; // 如果机器人i需要清扫的区域超出了当前已清扫的范围,则返回false
        if(s >= a[i]) s = a[i] + x - 1; // 如果当前已清扫的范围已经包含了机器人i的位置,则更新s为机器人i的清扫结束位置
        else s += x; // 否则,将s向前推进x个方格
    }
    return s >= n; // 如果s到达或超过了走廊的最后一个方格,则说明所有方格都被清扫过,返回true
}

int main() {
    cin >> n >> k; // 从标准输入读取走廊的方格数和机器人的数量
    for(int i = 0; i < k; i++) // 遍历并读取每台机器人的初始位置
        cin >> a[i];
    sort(a, a + k); // 对机器人的初始位置进行排序,这有助于后续的二分查找

    // 二分查找,查找满足条件的最小时间x
    int l = 0, r = n; // 定义二分查找的左右边界,初始时左边界为0,右边界为走廊的方格数n
    while(l < r) { // 当左边界小于右边界时,继续查找
        int mid = l + r >> 1; // 计算中间值mid
        if(check(mid)) r = mid; // 如果在时间x下可以完成清扫,则尝试查找更小的时间
        else l = mid + 1; // 否则,需要增加时间
    }
    cout << 2 * (r - 1) << endl; // 输出最终结果,即2倍的最小时间(因为题目要求的是最少花费的时间的两倍)
    return 0; // 程序结束
}

这段代码使用了二分查找算法来找到满足条件的最小时间x。在每次迭代中,它都会检查一个中间值是否满足条件,然后根据结果调整查找范围。最终找到的最小时间x是满足所有方格至少被清扫一次且机器人能够返回出发点的最小时间。由于题目要求输出的是这个时间的两倍,所以在输出时乘以2。

相关推荐
我是谁??2 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
南宫生34 分钟前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
发霉的闲鱼35 分钟前
MFC 重写了listControl类(类名为A),并把双击事件的处理函数定义在A中,主窗口如何接收表格是否被双击
c++·mfc
小c君tt38 分钟前
MFC中Excel的导入以及使用步骤
c++·excel·mfc
xiaoxiao涛1 小时前
协程6 --- HOOK
c++·协程
羊小猪~~3 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
脉牛杂德4 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz4 小时前
STL--哈希
c++·算法·哈希算法
CSUC4 小时前
【C++】父类参数有默认值时子类构造函数列表中可以省略该参数
c++
Vanranrr4 小时前
C++ QT
java·c++·qt