题目链接:http://codeforces.com/contest/782/problem/B
题目大意:
给出n,代表有n个人,第二行给出n个人的位置,第三行给出n个人的速度,求最小的时间n个人能聚在一块。
分析:
数据很大,用二分搜索时间,在这个时间内,一个人能向下向上走,有一个范围,如果所有人的范围都相交,则在小于这个时间内也能相遇,在此二分。判断是否有交集。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=60000+5;
class node
{
public:
double x,v;//x代表位置,v代表速度
};
node p[maxn];
int main()
{
//读取数据
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf",&p[i].x);
for(int i=0;i<n;i++)
scanf("%lf",&p[i].v);
double left=0,right=1000000000;
double res;
//二分搜索
while(fabs(right-left)>=1e-6)//精度控制
{
double mid=(left+right)/2;
// cout<<mid<<endl;
double x1,x2; //x1,x2分别记录相交范围的左端点,右端点
bool flag=true; //标记是否有交集
for(int i=0;i<n;i++)
{
double l=p[i].x*1.0-mid*p[i].v; //第i个人路径最小值
double r=p[i].x*1.0+mid*p[i].v; //第i个人路径最大值
if(i==0)
{
x1=l;
x2=r;
}
else
{
if(x1>r||x2<l) //不存在相交集合
flag=false;
if(x1<=l)
x1=l;
if(x2>=r)
x2=r;
}
}
if(flag)
{
right=mid;
res=mid;
}
else
left=mid;
}
printf("%.7lf\n",res); //精度控制,注意.6会在第36个样例错误
}