Codeforces Round #441 (Div. 1, by Moscow Team Olympiad) E. Delivery Club

E. Delivery Club

Problem Statement

    Petya and Vasya got employed as couriers. During the working day they are to deliver packages to n different points on the line. According to the company’s internal rules, the delivery of packages must be carried out strictly in a certain order. Initially, Petya is at the point with the coordinate s1 , Vasya is at the point with the coordinate s2 , and the clients are at the points x1 ,  x2 , …,  xn in the order of the required visit.
    The guys agree in advance who of them will deliver the package to which of the customers, and then they act as follows. When the package for the i-th client is delivered, the one who delivers the package to the (i + 1)-st client is sent to the path (it can be the same person who went to the point xi , or the other). The friend who is not busy in delivering the current package, is standing still.
    To communicate with each other, the guys have got walkie-talkies. The walkie-talkies work rather poorly at great distances, so Petya and Vasya want to distribute the orders so that the maximum distance between them during the day is as low as possible. Help Petya and Vasya to minimize the maximum distance between them, observing all delivery rules.

Input

    The first line contains three integers n, s1 , s2 (1 ≤ n ≤ 100 000, 0 ≤  s1 ,  s2  ≤  109 ) — number of points of delivery and starting positions of Petya and Vasya.
    The second line contains n integers x1 ,  x2 , …,  xn — customers coordinates (0 ≤  xi  ≤  109 ), in the order to make a delivery.
    It is guaranteed, that among the numbers s1 ,  s2 ,  x1 , …,  xn there are no two equal.

Output

    Output the only integer, minimum possible maximal distance between couriers during delivery.

Examples

Example 1
    Input
        2 0 10
        5 6
    Output
        10
Example 2
    Input
        3 2 1
        3 4 5
    Output
        1
Example 3
    Input
        1 4 5
        2
    Output
        2

Note

    In the first test case the initial distance between the couriers is 10. This value will be the answer, for example, Petya can perform both deliveries, and Vasya will remain at the starting point.
    In the second test case you can optimally act, for example, like this: Vasya delivers the package to the first customer, Petya to the second and, finally, Vasya delivers the package to the third client. With this order of delivery, the distance between the couriers will never exceed 1.
    In the third test case only two variants are possible: if the delivery of a single package is carried out by Petya, the maximum distance between them will be 5 - 2 = 3. If Vasya will deliver the package, the maximum distance is 4 - 2 = 2. The latter method is optimal.

题意

    给出一条数轴,并给出两个人起始的位置,之后按顺序给出n个点,两个人需要按照顺序到达一些点,每个点只有一个人可以走,求两个人任意时刻时最短距离的最大值。

思路

    看到“最短距离的最大值”,我们就可以想到二分,实际上这道题就是二分。我们可以先二分答案x,然后从后往前推,考虑现在可以到达的区间范围[a[i]-x,a[i]+x],然后对于a[i-1],如果它在[a[i]-x,a[i]+x]的范围内,那么就可以让站在a[i-1]的人不动,把另一个人移到a[i]这个位置,这样不会超过我们二分的值,如果不在范围内,我们就要取[a[i]-x,a[i]+x]和[a[i-1]-x,a[i-1]+x]区间的交,不然如果不在这个区间内,其他点都会有可能与这两个点的其中一个点距离大于x,那么就不符合题意了,最后扫完之后,如果可以那么就是(s1>=l&&s1<=r)||(s2>=l&&s2<=r),不然就是不行,最后二分的答案就是结果。

Code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>
inline void read(T &x) {
    Finish_read=0;x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    x*=f;Finish_read=1;
}
template<class T>
inline void print(T x) {
    if(x/10!=0)
        print(x/10);
    putchar(x%10+'0');
}
template<class T>
inline void writeln(T x) {
    if(x<0)
        putchar('-');
    x=abs(x);
    print(x);
    putchar('\n');
}
template<class T>
inline void write(T x) {
    if(x<0)
        putchar('-');
    x=abs(x);
    print(x);
}
/*================Header Template==============*/
int s,t,p[100010],n;
set<int>st; 
inline bool check(int x) {
    int l=p[n]-x,r=p[n]+x;
    for(int i=n-1;i;i--)
        if(l<=p[i]&&r>=p[i]) {
            l=p[i]-x;
            r=p[i]+x;
        }
        else {
            l=max(l,p[i]-x);
            r=min(r,p[i]+x);
        }
    return (s>=l&&s<=r)||(t>=l&&t<=r);
}
int main() {
    read(n);
    read(s);
    read(t);
    for(int i=1;i<=n;i++)
        read(p[i]);
    int l=abs(s-t),r=1e9+7,ans=2e9;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(check(mid)) {
            ans=min(ans,mid);
            r=mid-1;
        }
        else
            l=mid+1;
    }
    writeln(ans);
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值