题目链接:
http://codeforces.com/contest/782/problem/B
题解:
题目大意:有N个人在一条从南到北的街上。给出每个人在这条街上的位置,以及每个人最大的移动的速度,让你选出一个点,使得每个人到这个点的时间最小。(注意:这里的点不一定是整数点)
可以用二分时间的思想去做(因为不是整数点),每次比较在这个时间的条件下,是不是能够使得所有的点都满足。(即:算出这个时间下,所有点的左右区间,看看是不是都有交集)。如果不满足的话,就扩大搜索的区间,满足的话就缩小搜索的区间。这里有一个比较坑的地方就是:这里的EPS只能是1 E-6,如果自己提高精度的话,会超时(高精度可能会导致判断的条件进入死循环)。
这道题目应该还可以使用三分的思想,直接三分路径,判断时间来做。
代码:
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define eps 1e-6
const int maxn = 6e4+10;
int num1[maxn],num2[maxn];
int n;
bool check(double num)
{
double left,right;
for(int i=0;i<n;i++)
{
if(i==0)
{
left=num1[i]-num2[i]*num;
right=num1[i]+num2[i]*num;
}
else
{
double l=num1[i]-num2[i]*num;
double r=num1[i]+num2[i]*num;
if(l>right||r<left)
return false;
left=max(left,l);
right=min(right,r);
}
}
return true;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num1[i]);
for(int i=0;i<n;i++)
scanf("%d",&num2[i]);
double left=0,right=1e9,mid=0;//这里的right是还可以来优化的,可以把right变为在给出的条件里面的最大的时间。
while(right-left>eps)
{
mid=(left+right)/2;
if(check(mid))
right=mid;
else
left=mid;
}
printf("%.7f\n",left);
}