CF24E Berland collider 题解
分析
将时间二分,对于每一个二分得到的时间,从左至右搜每一个子弹,如果是从左往右飞的,就计算出它在这个时刻的坐标,取所有现坐标的最大值;如果是从右往左飞的,就看目前有没有从左往右飞的子弹此前能和它相遇,也就是比较它的现坐标是否小于从左往右飞子弹的现坐标最大值。如果能相遇,就更新答案,否则继续二分。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=5e5+7;
inline void qread(){}template<class T1,class ...T2>
inline void qread(T1 &a,T2&... b)
{
register T1 x=0;register bool f=false;char ch=getchar();
while(ch<'0') f|=(ch=='-'),ch=getchar();
while(ch>='0') x=(x*10)+(ch^48),ch=getchar();
x=(f?-x:x);a=x;qread(b...);
}
template<class T>inline T qmax(const T &x,const T &y){return x>y?x:y;}
template<class T>inline T qmin(const T &x,const T &y){return x<y?x:y;}
long long n;
struct node
{
long double x,v;
node(){;}
node(long double _x,long double _v):x(_x),v(_v){}
bool operator < (const node &o)const{return x<o.x;}
}a[MAXN];
bool check(long double mid)
{
long double mx=-1e30;
for(int i=0;i<n;i++)
{
if(a[i].v>0) mx=qmax(mx,a[i].x+a[i].v*mid);
else
{
long double t=(a[i].x+a[i].v*mid);
if(t<mx) return true;
}
}
return false;
}
long double ans;
signed main()
{
qread(n);int i,j;
for(i=0;i<n;i++) qread(a[i].x,a[i].v);
long double l=0,r=1e9+7;
while(r-l>=1e-10)
{
long double mid=(l+r)/2;
if(check(mid)) ans=r=mid;
else l=mid;
}
if(r==1e9+7) ans=-1;
printf("%.10Lf\n",ans);
return 0;
}