题意:两个邮递员,一个初始在s1,s2。需要依次给x1,x2,...,xn送快递。求所有时刻中两个邮递员的距离最大值的最小值。n<=100000,xi<=1e9.
标程:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N=100005; 5 int n,s1,s2,Max,l,r,ans,a[N]; 6 bool check(int d) 7 { 8 int l=a[n]-d,r=a[n]+d; 9 for (int i=n-1;i>=1;i--) 10 { 11 if (l<=a[i]&&a[i]<=r) l=a[i]-d,r=a[i]+d; 12 else l=max(l,a[i]-d),r=min(r,a[i]+d); 13 if (l>r) return 0; 14 } 15 if (l<=s1&&s1<=r||l<=s2&&s2<=r) return 1; 16 return 0; 17 } 18 int main() 19 { 20 scanf("%d%d%d",&n,&s1,&s2);Max=abs(s1-s2); 21 for (int i=1;i<=n;i++) scanf("%d",&a[i]),Max=max(Max,a[i]); 22 l=abs(s1-s2);r=Max; 23 while (l<=r) 24 { 25 int mid=(l+r)>>1; 26 if (check(mid)) r=mid-1,ans=mid;else l=mid+1; 27 } 28 printf("%d\n",ans); 29 return 0; 30 }
题解:二分答案+可行区间
最小化最大值一定是二分,转换成判定性问题,并且需要O(n)判定。
一个点最后一定在Xn,另一个点的范围Rn=[Xn-d,Xn+d]。
1.如果Xn-1在Rn中,移动不在Xn-1上的另一个点到Xn来满足限制。另一个点的范围Rn-1=[Xn-1-d,Xn-1+d]。
2.如果Xn-1不在Rn中,移动在Xn-1的那个点到Xn,另一个点的范围Rn-1=[Xn-1-d,Xn-1+d]∩Rn。
如果Ri为空则不可行。如果最后R1中不包含s1和s2,那么也不可行。