题目描述
小明公司的办公区有一条长长的走廊,由 NN 个方格区域组成,如下图所示。
走廊内部署了 KK 台扫地机器人,其中第 ii 台在第 AiAi 个方格区域中。已知扫地机器人每分钟可以移动到左右相邻的方格中,并将该区域清扫干净。
请你编写一个程序,计算每台机器人的清扫路线,使得
-
它们最终都返回出发方格,
-
每个方格区域都至少被清扫一遍,
-
从机器人开始行动到最后一台机器人归位花费的时间最少。
注意多台机器人可以同时清扫同一方块区域,它们不会互相影响。
输出最少花费的时间。 在上图所示的例子中,最少花费时间是 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,KN,K。
接下来 KK 行,每行一个整数 AiAi。
其中,1≤K<N≤105,1≤Ai≤N1≤K<N≤105,1≤Ai≤N。
输出描述
输出一个整数表示答案。
输入输出样例
示例
输入
10 3
5
2
10
输出
6
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
import java.util.Arrays;
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static int K, N;
static int[] robot;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码..
//走廊总长度N
N = scan.nextInt();
//机器人总数K
K = scan.nextInt();
//存储机器人的坐标
robot = new int[K];
for (int i = 0; i < K; i++) {
robot[i] = scan.nextInt();
}
//机器人坐标从小到大排序
Arrays.sort(robot);
//二分查找,不超过最长N
int left = 0;
int right = N;
int middle = (left + right) / 2;
while (left < right) {
if (check(middle)) {
//如果中值可以,尝试缩小
right = middle;
} else {
//如果不行则尝试放大
left = middle+1;
}
middle = (left + right) / 2;
}
//left==right 的时候跳出,查找结束,得到最小值
System.out.println((left - 1) * 2);
}
private static boolean check(int num) {
//标识上一个机器人能打扫到的最右侧坐标
int rightline = 0;
for (int i : robot) {
//如果这个机器人打扫的左边界小于上一个的右边界则有效
if (i - num <= rightline) {
if (i <= rightline)
//如果机器人本身在右边界内,这样更新右边界
rightline = i + num - 1;
else
//如果机器人本身在右边界外,这样更新
rightline = rightline + num;
} else {
return false;
}
}
//代表能全打扫完
return rightline >= N;
}
}