第十届蓝桥杯省赛C++C/研究生组,第十届蓝桥杯省赛JAVAC/研究生组——扫地机器人题解(二分)

题目描述

小明公司的办公区有一条长长的走廊,由 N个方格区域组成,如下图所示。
在这里插入图片描述
走廊内部署了 K台扫地机器人,其中第 i台在第 A i A_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。
第十届蓝桥杯省赛C++C/研究生组,第十届蓝桥杯省赛JAVAC/研究生组——扫地机器人题解(二分)_第1张图片
输入样例

10 3
5
2
10

输出样例

6

思路分析

二分
本题的要求是归位最慢的机器人归位花费时间最短,这种问题很显然是采用二分答案的方法。
从案例可以看出,清扫4个单位长度的区域花费3秒,不难推出清扫区域长度(len)和花费时间(time)的关系
t i m e = ( l e n − 1 ) ∗ 2 time = (len - 1) * 2 time=(len1)2
所有要求的最短的时间,也就是求清扫全部区域,清扫区域最长的机器人的清扫长度最短
(有点绕,请多读读上下文理解)
清扫范围进行二分,然后验证其答案的正确性即可
贪心策略
我们首先把每个机器人的位置进行排序,清扫范围固定时(二分清扫范围再说一遍),当机器人不能把他左侧的区域全部扫完,其右侧的机器人一定也扫不到该区域,固这种情况下清扫范围太小。

代码

代码如下

#include 
#include 

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;
} 

==创作不易,阁下的赞可以让作者快乐一整天 ^_^ ==

你可能感兴趣的:(题解,蓝桥杯,c++,c语言)