题目描述
小明公司的办公区有一条长长的走廊,由 N个方格区域组成,如下图所示。
走廊内部署了 K台扫地机器人,其中第 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。
输入样例
10 3
5
2
10
输出样例
6
思路分析
二分
本题的要求是归位最慢的机器人归位花费时间最短,这种问题很显然是采用二分答案的方法。
从案例可以看出,清扫4个单位长度的区域花费3秒,不难推出清扫区域长度(len)和花费时间(time)的关系
t
i
m
e
=
(
l
e
n
−
1
)
∗
2
time = (len - 1) * 2
time=(len−1)∗2
所有要求的最短的时间,也就是求清扫全部区域,清扫区域最长的机器人的清扫长度最短
(有点绕,请多读读上下文理解)
对清扫范围进行二分,然后验证其答案的正确性即可
贪心策略
我们首先把每个机器人的位置进行排序,清扫范围固定时(二分清扫范围再说一遍),当机器人不能把他左侧的区域全部扫完,其右侧的机器人一定也扫不到该区域,固这种情况下清扫范围太小。
代码
代码如下
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int a[N];
int n, k;
bool check(int len) {
int p = 0;
for (int i = 1; i <= k; i ++) {
if (a[i] - len > p)
return false;
if (p >= a[i])
p = a[i] + len - 1;
else
p += len;
}
return p >= n;
}
// time = (len - 1) / 2;
int main() {
cin >> n >> k;
for (int i = 1; i <= k; i ++)
cin >> a[i];
sort(a + 1, a + k + 1);
int l = 0, r = n;
// 扫的距离越长, 时间越长, 大概率都可以通过。
while (l < r) {
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
cout << (l - 1) * 2 << endl;
return 0;
}
==创作不易,阁下的赞可以让作者快乐一整天 ^_^
==