第十届蓝桥杯java-c组-扫地机器人

1. 问题描述:

小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所示。走廊内部署了 K 台扫地机器人,其中第 i 台在第 Ai 个方格区域中。 已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净。请你编写一个程序,计算每台机器人的清扫路线,使得它们最终都返回出发方格,每个方格区域都至少被清扫一遍,从机器人开始行动到最后一台机器人归位花费的时间最少。注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。
输出最少花费的时间。 在上图所示的例子中,最少花费时间是 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
【评测用例规模与约定】
对于 30% 的评测用例,1≤ K < N ≤10。 对于 60% 的评测用例,1≤ K < N ≤1000。 对于所有评测用例,1≤ K < N ≤100000,1≤ Ai ≤ N。

2. 思路分析:

① 一开始的时候没有什么思路,于是找了一下网上的博客看了一下,发现理解之后还是可以解决的,在c语言网中找到一个比较好理解的代码将其转换为了python。这道题目的答案其实取决于最后一个机器人完成扫地任务之后回到自己位置的时间,所以K个机器人必须相互合作,只有当K个机器人完成打扫的区域平均的时候这个时候使用的时间是最短的,因为这个时候是同时进行工作的。分析题目可以知道每一个机器人可以打扫的最少区域的长度为max(robots[0],n // k),最大的长度为n,所以我们在这个范围中找到一个值使得机器人打扫的区域能够满足题目的要求(其实可以使用二分查找进行解决耗时会更短)

 ② 我们的策略是根据当前传递进方法中的打扫的区间长度,根据每个机器人的位置以及打扫区间的长度、左边界l的位置来更新下一个机器人打扫的左边界(每个机器人完成各自打扫的任务),所以一开始的时候就需要声明一个左边界变量用来记录下一个机器人开始打扫的左边界,在更新左边界的时候发现不满足题目的条件的时候可以直接返回False,当循环结束检查一下机器人能够打扫的最大范围,看是否大于等于了N,如果满足可以返回True,否则返回False

③ 判断传递的当前打扫区间长度是否满足题目条件的时候核心的就为下面的代码:

当机器人出现在边界左边时 ( L : 边界 , i : 当前机器人的下标 , Q : 区间大小 )
L = i + Q -1
当机器人出现在边界右边时
L = i + Q - ( i - L)

④ 可以在c语言网测试代码

3. 代码如下:

from typing import List


def f(l: int, Q: int, robots: List[int]):
    for i in range(k):
        if robots[i] - Q <= l:
            if robots[i] <= l:
                l = robots[i] + Q - 1
            else:
                l = robots[i] + Q - (robots[i] - l)
        else:
            return False
    if l < n: return False
    return True


if __name__ == '__main__':
    n, k = map(int, input().split())
    robots = list()
    for i in range(k):
        robots.append(int(input()))
    robots.sort()
    Q = n // k if n // k >= robots[0] else robots[0]
    while Q <= n:
        l = 0
        if f(l, Q, robots): break
        Q += 1
    print(2 * (Q - 1))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值