CF875E Delivery Club

题目传送门:CF875E

洛谷入口

题目大意:

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

数据范围

\(\circ\) \(1\le n\le10^5\)
\(\circ\) \(0\le s1,s2\le10^9\)
\(\circ\) \(0\le x_i\le10^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(n\log 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

posted @ 2020-04-09 23:12  Realityang  阅读(249)  评论(0编辑  收藏  举报