题目链接:http://codeforces.com/problemset/problem/1041/D
题目简单说明:就是给定一个高度,然后有人从飞机跳下,通过滑翔机让自己每秒向右移动一个单位同时向下移动一个单位,当落地的时候就停止移动。现在有若干气流,当他滑行时经过气流时,不会下降但是会右移。他可以从任何位置跳下,但是高度一定。问:他能够向右移的最大距离。
解题思路:首先这道题我们关注的应该是气流的位置和他们的宽度。气流的宽度对高度没有影响,所以我们只关注气流之间的距离。很明显,我们应该寻找的是一个连续的气流,他们之间的距离之和不超过高度。因为是查找连续的气流,所以气流的宽度和间距都应该是前缀和。这样方便我们寻找。不然,循环求和肯定会超时。寻找用二分查就可以了。临界情况需要注意。我代码中会有临界情况的处理,在这里不多说。至于为什么,读者可以自行思考。
程序代码:
#include <bits/stdc++.h>
using namespace std;
struct seg{
int x1;
int x2;
}s[200005];
int n,h,m[200005];
vector<int> d;
int main(){
scanf("%d%d%d%d",&n,&h,&s[0].x1,&s[0].x2);
m[0]=0;d.push_back(0);
for(int i=1;i<n;i++){
scanf("%d%d",&s[i].x1,&s[i].x2);
d.push_back(s[i].x1-s[i-1].x2+d[i-1]);
m[i]=s[i-1].x2-s[i-1].x1+m[i-1];
}
m[n]=s[n-1].x2-s[n-1].x1+m[n-1];
int ans=0;
for(int l=0;l<n;l++){
int r=upper_bound(d.begin(),d.end(),h+d[l])-d.begin()-1;
//考虑临界情况
if(d[r]-d[l]<h){ans=max(ans,h+m[r+1]-m[l]); }
if(d[r]-d[l]==h){ans=max(ans,max(s[r].x1-s[l].x1,s[r].x2-s[l].x2)); }
}
cout<<ans;
return 0;
}