zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    [转]CROSS APPLY 和outer apply 的区别
    第一次WCF部署成功心得(UP+证书)
    .NET 简单实现广播
    【转】 c#注册全局快捷键
    软件人才成长链
    [转]关于VS2005智能设备中无法找到PInvoke DLL问题
    [转]我倡导无政府主义编程—Fred George访谈录
    运行Windows Mobile程序时报错:无法找到 PInvoke DLL SQLite.Interop.065.DLL
    系统分析师考试说明
    [转]Oracle 字符集的查看和修改
  • 原文地址:https://www.cnblogs.com/yang-RA-NOI/p/12670427.html
Copyright © 2011-2022 走看看