CodeForces 782B The Meeting Place Cannot Be Changed(二分)

来源:互联网 发布:python网络编程 amazon 编辑:程序博客网 时间:2024/05/01 10:45

题目大意:有一条从南到北的道路,根据最南建筑到北的方向延伸,有一系列的坐标,这条道路上有一些点,一共有n个朋友(这些点里一个点一个朋友),他们任一个站立在xi米的地方,可以沿着道路的两个方向的任何一个方向,以不超过每秒6米的速度移动:南或北。你要计算在路上的某个时刻收集所有n个朋友所需的最短时间。(注意:他们最短时间内达到的共同位置不一定为整数坐标)

解题思路:这个题看懂了应该就明白是二分了,关键是怎么去二分,首先我想着二分距离,但是,因为求的是时间,如果二分距离,根本枚举不完,因为这个位置可以是小数,所以换思路,枚举时间,二分判断能不能在二分出的时间mid内求出这个最小时间,在排序后的点里,先提出第一个点(最左边那一个),再用循环,将点两两比较,取交集直到取出全部的共同交集,如果有则为所求时间,如果没有则继续二分。

  我这代码……还是调了好几遍细节才出来的……

代码奉上:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int maxn=1e5;int n;double ans;struct node{    int x,v;    bool operator < (const node &a)const    {        return x<a.x;    }} mapn[maxn];bool erfen(double mid)  //判断二分出来的时间够不够用{    double time;    double a=mapn[1].x-mapn[1].v*mid;      //之前写的int wa了……    double b=mapn[1].x+mapn[1].v*mid;    for(int i=2; i<=n; i++)    {        double c=mapn[i].x-mapn[i].v*mid;        double d=mapn[i].x+mapn[i].v*mid;        if(a<c) a=c;        if(b>d) b=d;        if(a>b) return false;    }    return true;}int main(){    while(~scanf("%d",&n))    {        for(int i=1; i<=n; i++)            scanf("%d",&mapn[i].x);        for(int i=1; i<=n; i++)            scanf("%d",&mapn[i].v);        sort(mapn+1,mapn+n+1);        double l=0,r=1e9;        double mid;        while(r-l>1e-6)        {            mid=(l+r)/2;            bool flag=erfen(mid);            if(flag)            {                ans=mid;                r=mid;            }            else            {                l=mid;            }        }        printf("%.12lf\n",ans);   //没手动控制精度,也wa 了    }    return 0;}



~step by step

阅读全文
0 0