题目描述

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

走廊内部署了 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

【思路及代码】

        本题属于二分算法题目,求最短的花费时间,所以可以对花费的时间使用二分来求解,最短的时间就是每个位置都已打扫完0,最长就是只有一台机器需要打扫n个地点且要回到原点,所以花费时间最长为2*n.

        需要找最小值,所以采用如下的二分模板

        while(l<r)

        {

                int mid=(l+r)>>1;

                if(check(mid))//符合条件

                        r=mid;//接着向左寻找最小值

                else l=mid+1;

        }

使用last记录需要打扫的最后位置,具体代码如下

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int n,st[N],k;
bool check(int mid)
{
	//if(mid<(a[1]-1)*2||mid<(n-a[k])*2)
	//	return false;
	int last=1;
	for(int i=1;i<=k;i++)
	{
		if(a[i]>last)//向左扫
		{
			if(a[i]-last>mid/2)
				return false;
			else if(a[i]-last==mid/2)
				last=a[i]+1;
			else if(a[i]-last<mid/2)
				last=a[i]+(mid/2-a[i]+last)+1;
		} 
		else if(a[i]<=last)//向右扫 
		{
			last=max(last,a[i]+mid/2+1);
		}
		/* 
		if(a[i]-last>mid/2)
			return false;
		if((a[i]-last)==mid/2) last=a[i];
		else if((a[i]-last)<mid/2) 
			last=a[i]+(mid/2-a[i]+last);
		*/
	}	 
	if(last>n) return true;
	else
	return false;
}
int main()
{
	cin>>n>>k;
	for(int i=1;i<=k;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+1+k);//按照所在位置的先后位置排序 
	int l=0,r=2*n;//最长用的时间 
	while(l<r)
	{
		int mid=(l+r)/2;
		if(check(mid))
			r=mid;
		else l=mid+1;
	}
	cout<<l;
	return 0;
}

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐