2248. 【2017.12.02普及组模拟】送快递

题目:

2248. 【2017.12.02普及组模拟】送快递 

时间限制: 3000 ms  空间限制: 512000 KB  
题目描述
        Petya和Vasya被聘为快递员。在工作日期间,他们将提供包裹到线上的不同点。根据公司的内部规定,包裹的交付必须严格按照一定的顺序进行。最初,Petya处于坐标s1的点,Vasya位于坐标s2的点,n个顾客所需访问的顺序位于点x1,x2,...,xn。
        这些人预先同意他们谁将交付给哪些客户,然后他们的行为如下。当第i个客户端的包裹被交付时,两个快递员中的其中一个负责去送第i+1个。此时不送快递员的那个原地不动。即快递是严格按照顾客顺序一个个在送的,一个快递员在送的时候,另一个快递员是不动的。
         由于要相互沟通,这些家伙有对讲机。对讲机的工作距离不是很远,所以Petya和Vasya想在送快递的时候,使得他们的最大距离尽可能低。帮助Petya和Vasya尽量减少他们之间的最大距离,遵守所有交货规则。
输入
      第一行包含三个整数n,s1,s2(1≤n≤100000,0≤s1,s2≤10^9) - Petya和Vasya的送货数量和起始位置。
      第二行包含n个整数x1,x2,...,xn - 客户坐标(0≤xi≤10^9),以便交货。
      保证,在数字s1,s2,x1,...,xn中没有两个相等。
输出
只有一行一个正数,即最小可能的最大距离。
样例输入1
2 0 10
5 6
样例输入2
3 2 1
3 4 5
样例输入3
1 4 5
2
样例输出1
10
样例输出2
1
样例输出3

2

注意
         在第一个测试案例中,快递员之间的初始距离为10.这个值将是答案,例如,Petya可以执行两次交付,Vasya将保持在起点。
        在第二个测试用例中,您可以通过以下方式进行最佳的操作:Vasya向第一个客户送货,Petya到第二个,最后,Vasya将包提供给第三个客户。按照这种交货顺序,快递员之间的距离不会超过1。
        在第三个测试用例中,只有两种情况是可能的:如果单个包装的交付由Petya执行,则它们之间的最大距离为5 - 2 = 3.如果Vasya将提供包装,最大距离为4 - 2 = 2.后一种方法是最优的。
数据范围限制
对于20%的数据,n<=25
对于40%的数据, n<=100
对于60%的数据, n<=2000
对于100%的数据,n<=100000
 

 

题解:

100分:

首先我们二分答案,并判断二分得到的mid是否合法。

怎么判断呢?

还是我讲题时的那副图:


不难发现,第i层就是a[-1],a[i];  a[0],a[i];  a[1],a[i];……  a[i-1],a[i]。

 

事实上我们只存储合法的a[k],a[i]值,也就是说如果a[0],a[i]不合法,第i层就不会出现a[0],a[i]。

 

而a[k],a[i]合法的条件是abs(a[k]-a[i])<=mid且a[k],a[i-1]合法;

特殊地,如果k=i-1,即a[k],a[i-1]不存在,那么要使a[k],a[i]合法,要满足一下条件:

1、abs(a[k]-a[i])<=mid;

2、a[-1..k-1],a[k]中,至少有一个合法。

 

最后,如果我们做到第n层时还有东西合法,二分的mid就是合法的,反之,就是不合法的。

 

那么,怎么去实现呢?

实际上,这题的解法有很多种,但都是根据上述思路演变而来,只是实现方法的有所不同。

这题可以用平衡树(c++自带有set),但由于很多同学(包括我)不会用,所以我们尝试思考一下别的做法。

 

我们考虑一层一层来模拟。

但是很快就会发现如果mid合法,最坏的枚举效率是O(n^2)的。

也就是说只有六十分。

 

我们再继续想,按层模拟不行,是因为如果有合法的就一定得模拟到第n层。如果我们按列来模拟,只要有一列到得了第n层,后面的列都可以不用枚举了。

 

判断二分mid是否合法,实质就是判断是否至少有一个a[i],a[n]合法。

 

而前面已经讲了,如果 a[i],a[n]合法,则abs(a[i]-a[n])<=mid且a[i],[n-1]合法,而要a[i],[n-1]合法,则……可以看出这实际上是一个递推的过程。直到判断到a[i],a[i+1]的时候,abs(a[i]-a[i+1])<=mid且a[-1..i-1],a[i]中,至少有一个合法。

 

所以我们枚举a[i],a[n]是否合法,从最上面下来,一旦有一个不合法,就中断,且a[i],a[n]不合法。如果能够到达第n层,那么二分的mid是合法的。

我们还应记录下最深层的中断位置max,表示a[-1..max-1],a[max]至少有一个合法,如果i+1<=max那我们就继续看a[i+1],a[n]是否合法,反之,二分的mid是不合法的。

 

因为数据是随机构造,这个方法的时间复杂度还是很理想的。

 

 

用这种方法比用平衡树(c++自带set)快了整整500毫秒。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值