Python:扫地机器人(二分法)

题目描述

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

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

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

  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​。

其中,1≤K<N≤105,1≤Ai​≤N。

输出描述

输出一个整数表示答案。

输入输出样例

输入

10 3
5
2
10

输出

6

思路: 

题目要求最少花费时间。由于每个机器人的工作时间可能不同,那么这些机器人各自的花费时间中的最大值(设为 t )的就是本题要求的答案,我们需要做的是使得 t 最小。将最大花费时间(t)最小化,显然我们需要使用二分求解。

我们假设某个机器人需要清扫 a,b,c,d​ 四个格子,因为这个机器人清扫完还需要回到最初始的位置,所以无论这个机器人初始位置在什么地方,其清扫路径的本质都是重复两次 a​ 到 b​,b​ 到 c​,c​ 到 d​ 的过程,花费时间为 6​,由此,我们假设某个机器人清扫的格子范围为 l​, 那么这个机器人花费的时间为 (l−1)×2​。所以我们只需要对机器人清扫的范围(l​)进行二分即可,最后的答案为 t=(l−1)×2​。

显然当每个机器人清扫的范围大小相同时,花费时间最小。我们可以对清扫范围进行二分,然后验证其答案的正确性即可,判断条件是清扫范围可以使得每个格子都能够扫到。

参考代码: 

n,k=map(int,input().split())
a=[0]    #这里加个0是因为下面从1开始
for i in range(k):
  a.append(int(input()))
a.sort()  #从小到大排序

def check(d):  # 检查每一个清理距离是否能将走廊清理完成
  len=0   #覆盖长度,从最左端开始一直到最右端
  for i in range(1,k+1):
    if len+d>=a[i]:
      if len>a[i]:
        len=a[i]+d-1  #这里减1是因为自己本身也需要清理
      else:   #否则直接就是当前长度+d
        len+=d
    else:
      return False
  return len>=n
l,r=1,n   #最短是1,最长是n
while l<r:    #二分查找计算清扫范围
  mid=(l+r)//2
  if check(mid):
    r=mid
  else:
    l=mid+1
print((l-1)*2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的敲码工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值