cf 782b

来源:互联网 发布:斗鱼刷屏软件 编辑:程序博客网 时间:2024/05/19 03:18

这个题的写法有两种一种是对于时间二分,一种是对于那个相遇的坐标二分,两种做法都有尝试

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.

Example
Input
37 1 31 2 1
Output
2.000000000000
Input
45 10 3 22 3 2 4
Output
1.400000000000
下面先贴,关于时间的二分的做法

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <vector>#include <map>#include <math.h>#include <stack>#define LL long longusing namespace std;const int INF = 0x3f3f3f3f;int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};const int maxn = 60000 + 10;int k[maxn];int s[maxn];int n;bool judge(double t){    double ri,le;    ri = k[0] + t * s[0];    le = k[0] - t * s[0];    for(int i = 0; i <n; i++)    {        //if(i == 0)        //{        //    ri = k[0] + t * s[0];       //     le = k[0] - t * s[0];        //}        double ri1 = k[i] + t* s[i];        double le1 = k[i] - t* s[i];        if(ri1 < le || le1 > ri)        {            return false;        }        ri = min(ri,ri1);        le = max(le,le1);    }    return true;}int main(){    double min_n = INF;    double max_n = 0;    //double l,r;    scanf("%d",&n);    for(int i = 0; i < n; i++)    {        scanf("%d",&k[i]);    }    for(int i = 0 ; i < n; i++)    {        scanf("%d",&s[i]);    }    //  cout<<max_n<<" "<<min_n<<endl;    double l = 0,r = 1e9;    while(r - l > 1e-6)    {        double mid = (r+l) / 2;        if(judge(mid))        {            r = mid;        }        else            l = mid;    }    printf("%.7lf",r);    return 0;}
再贴关于距离二分的做法

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <vector>#include <map>#include <math.h>#include <stack>#define LL long longusing namespace std;const int INF = 0x3f3f3f3f;int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};const int maxn = 60000 + 10;double k[maxn];double s[maxn];int main(){    int n;    double min_n = INF;    double max_n = 0;    //double l,r;    scanf("%d",&n);    for(int i = 0; i < n; i++)    {        scanf("%lf",&k[i]);        min_n = min(min_n,k[i]);        max_n = max(max_n,k[i]);    }    for(int i = 0 ; i < n; i++)    {        scanf("%lf",&s[i]);    }    //  cout<<max_n<<" "<<min_n<<endl;    double cur = INF;    while(min_n <= max_n)    {        double mid = (min_n + max_n)/2,x;        double sum = 0;        for(int i = 0; i < n; i++)        {            double a = fabs(k[i] - mid) / s[i];            if(sum < a)            {                sum = a;                x = k[i];            }        }        //cout<<x<<endl;        //cout<<cur<<endl;        cur = min(sum,cur);        if(mid <= x)        {            min_n = mid + 0.000001;        }        else        {            max_n = mid - 0.000001;        }    }    printf("%lf\n",cur);    return 0;}

这两种二分的方法都可以,以后想问题的方法还是要多元化一点

原创粉丝点击