• CF875E Delivery Club


    题目传送门:CF875E

    洛谷入口

    题目大意:

    (有两个人在一根数轴上送货,起初一个人在s1, 一个人在s2)
    (一共有 n 个订单要送,严格按照时间顺序,第 i 个订单要送到数轴上的 x_i 位置。)
    (每个订单恰好一个人去送,且在这个过程当中另一人始终保持在原地不动)
    (你可以安排每个订单由哪个人去送,从而最小化整个过程中两个人之间的最大距离)

    数据范围

    (circ) (1le nle10^5)
    (circ) (0le s1,s2le10^9)
    (circ) (0le x_ile10^9)
    (数据保证 s_1,s_2,x_1,x_2,...,x_n 两两不等)

    题解

    这题中提到“最小化最大距离”
    我们会想到去二分这个距离
    然后要尝试用O(n)的时间复杂度
    判断这个二分出的距离是否可能
    那么按题意,在最后会有一个人(称为A)在(a_n)的位置上
    倒过来想,会产生一个区间,即:(Q_n=[a_n-x,a_n+x])
    并假设初始所有区间(Q_i=[a_i-x,a_i+x])
    若当时开始讨论i这个点
    另一个人(称为B)在区间(Q_{i+1})
    那可以B直接走这个i点,区间(Q_i)不作修改
    但如果B不在(Q_{i+1})
    那只能由A亲自走i点,区间就是(Q_i和Q_{i+1})的交集
    然后要防止这个区间被刷为空集,即l<r
    一旦不符合就表示不行
    安排完区间(Q_1)后要保证在这个区间内
    s1和s2中至少有一个在里面
    如果这些阻挠都没有困住这个x,恭喜它,它是可能的答案
    然后二分算法就不多赘述了
    总体时间复杂度(O(nlog n))
    (好像这题对于各位visitor来说应该很简单,但是还是细解了QwQ)
    此题完结!!!下见代码↓↓↓

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    int a[100010],s1,s2,ans,n;
    bool check(int x){
    	int l=a[n]-x,r=a[n]+x;
    	for(int i=n-1;i>=1;i--){
    		if(a[i]>=l&&a[i]<=r)l=a[i]-x,r=a[i]+x;
    		else l=max(a[i]-x,l),r=min(a[i]+x,r);
    		if(l>r)return false;
    	}
    	if((s1<l||s1>r)&&(s2<l||s2>r))return false;
    	return true;
    }
    int main(){
    	cin>>n>>s1>>s2;
    	for(int i=1;i<=n;i++)cin>>a[i];
    	int l=abs(s1-s2),r=1e9;
    	while(l<=r){
    		int mid=l+r>>1;
    		if(check(mid))ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	cout<<ans;
    }
    

    (仅有24行……)

    支持一下吧,关注,点赞,评论都好!

    THE END

    Reality&Imagine
  • 相关阅读:
    二分查找
    选择排序算法
    1.2.2凑零钱问题(暴力递归+动态规划)
    1.2.1斐波那契数列4种解法(暴力递归+动态规划)
    二维数组查找
    插入排序算法
    母亲的爱今天是母亲节,和妈妈通话后回忆起往事
    冒泡排序算法
    Pandas使用入门
    pandas.contact函数
  • 原文地址:https://www.cnblogs.com/yang-RA-NOI/p/12670427.html
Copyright © 2020-2023  润新知