题目大意
小明公司的办公区有一条长长的走廊,由 N N N 个方格区域组成,如下图所示。
走廊内部署了 K K K 台扫地机器人,其中第 i i i 台在第 A i A_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。
解题思路
题目要求:最少花费时间。
由于每个机器人的工作时间可能不同,那么这些机器人各自的花费时间中的最大值(设为
t
t
t )的就是本题要求的答案,需要做的是使得
t
t
t 最小。将最大花费时间(
t
t
t)最小化。
假设某个机器人需要清扫
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d 四个格子(清扫完还需要回到最初始的位置);
清扫路径的本质:重复两次
a
a
a 到
b
b
b,
b
b
b 到
c
c
c,
c
c
c 到
d
d
d 的过程,花费时间为
6
6
6,由此,我们假设某个机器人清扫的格子范围为
l
l
l, 那么这个机器人花费的时间为
(
l
−
1
)
∗
2
(l-1)*2
(l−1)∗2。所以需要求解机器人清扫的范围(
l
l
l),最后的答案为
t
=
(
l
−
1
)
∗
2
t=(l-1)*2
t=(l−1)∗2。
贪心:最左边的格子由左边第一台机器人清扫,花费时间是最少的,采用贪心思想,让每台机器人都要优先清扫其左边还未扫的到格子,然后再往右扫,这样可以减少右边下一个机器人需要往左扫的范围,增加其往右扫的范围,以此类推。
当每个机器人清扫的范围大小相同时,可以对清扫范围进行二分,然后验证其答案的正确性即可,判断条件是清扫范围可以使得每个格子都能够扫到
综上,本题采用二分加贪心的思想解答。
AC_Code
# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
import os
import sys
# 数据的读入
N,K=map(int,input().split())
line=[]
for i in range(K):
line.append(int(input()))
# 排序之后便于检查
line.sort()
# 检查每一个清理距离是否能将走廊清理完成
def check(d):
pos=1
for i in range(len(line)):
if pos+d>=line[i]:
if i!=len(line)-1:pos=min(pos+d+1,N,line[i+1])
else:pos=min(pos+d,N)
else:return False
if pos>=N:return True
return False
# 进行二分查找,上界为N,下界为1
left,right=1,N
while left<right:
mid=(left+right)>>1
if check(mid):right=mid
else:left=mid+1
# 最后别忘了2倍
print(2*left)