二分心得

CodeForces - 782B

The main road in Bytecity is a straight line from south to north. Conveniently, there are coordinates measured in meters from the southernmost building in north direction.

At some points on the road there are n friends, and i-th of them is standing at the point xi meters and can move with any speed no greater than vi meters per second in any of the two directions along the road: south or north.

You are to compute the minimum time needed to gather all the n friends at some point on the road. Note that the point they meet at doesn't need to have integer coordinate.

input:

The first line contains single integer n (2 ≤ n ≤ 60 000) — the number of friends.

The second line contains n integers x1, x2, ..., xn (1 ≤ xi ≤ 109) — the current coordinates of the friends, in meters.

The third line contains n integers v1, v2, ..., vn (1 ≤ vi ≤ 109) — the maximum speeds of the friends, in meters per second.

output:

Print the minimum time (in seconds) needed for all the n friends to meet at some point on the road.

Your answer will be considered correct, if its absolute or relative error isn't greater than 10 - 6. Formally, let your answer be a, while jury's answer be b. Your answer will be considered correct if holds.
 

题意:挑选一个地点,让所有人到达此点的时间最短。

注意,每个人的速度不大于所给的值。

二分搜索的前提是在一个有序序列下进行的,因此,这个题应该以时间作为二分的依据,先让最左边的人全速前进,只要在规定时间内其他人的路程区间全都与第一个人的路程区间相交,就可说明t符合条件,因此t向更小的一边进行二分,反之则向最大的一面进行二分。

代码:

#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
int n;
struct node
{
    int pos,v;
}a[1008611];
bool judge(double time,double l,double r)
{
    int i;
    for(i=1;i<n;i++)
    {
        if(a[i].pos-a[i].v*time>r||a[i].pos+a[i].v*time<l)
        {
            return 0;
        }
        else
        {
            l=max(l,a[i].pos-a[i].v*time);
            r=min(r,a[i].pos+a[i].v*time);
        }
    }
    return 1;
}
bool cmp(node s1,node s2)
{
    return s1.pos<s2.pos;
}
int main()
{
    int i,j;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i].pos);
    }
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i].v);
    }
    sort(a,a+n,cmp);
    int t=10000;
    double l,r,mid,p,posl,posr;
    l=0;r=1e9+5;
    while(t--)
    {
        mid=(l+r)/2;
        posr=a[0].pos+a[0].v*mid;
        posl=a[0].pos-a[0].v*mid;
        if(judge(mid,posl,posr))
        {
            r=mid;
        }
        else
            l=mid;
    }
    printf("%lf\n",r);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a201707090/article/details/81253974