读——二分

题目:

  一个数轴,有N个寻找点,M个被查询点,查询点以1m/s的速度移动,从0s开始n个点开始移动,问覆盖到所有被查询点所用的最短时间?

 

思路:

  枚举结果(最短时间),查询时,对于每个查询点,会遍历两个区间,一个单倍,一个双倍长度。(长度和就是时间)

  判断对于当前长度能否覆盖所有被查询点。

 

#include<iostream >
#include<cstdio>
#include<queue>
#include<algorithm>
#include<math.h>
#include<cstring>
using namespace std;
int n,m;
long long  a[200009],b[200009],l,r,mid;
bool check(long long  x)
{
    long  long  tot=0,to;
    int last=1,last1;
    for(int i=1;i<=n;i++)
    {    
        if(b[last]<a[i])
        {
            if(a[i]-b[last]>x)    return 1;
            to=x+b[last]-(a[i]-b[last]);
            last1=last;
            while(b[last]<=to)    last++;//先左 
            
            tot=(x-(a[i]-b[last1]))/2+a[i];
            while(b[last1]<=tot)    last1++;
            
            last=max(last,last1);
        }else
        {
            to=x+a[i];
            while(b[last]<=to)    last++;
        }
        
    }
    if(last==m)    return 1;
    return 0;
}
int main()
{
    freopen("read.in","r",stdin);
    freopen("read.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=m;i++) scanf("%lld",&b[i]);
    b[m+1]=b[m]*12;    
    l=0,r=(max(a[n],b[m]))*2,mid;
    while( l<r )
    {
        mid=(l+r)>>1;
        if(check(mid)) l=mid+1;
        else r=mid;
    }
    cout<<r;
    return 0;
}

 

posted @ 2017-09-27 17:41  浪矢-CL  阅读(125)  评论(0编辑  收藏  举报