Codeforces 65 C. Harry Potter and the Golden Snitch
問題
点が(x[0],y[0],z[0])をスタートして、
折れ線(x[i],y[i],z[i])上を等速度vsで動く。
ハリーは、点(Px,Py,Pz)をスタートして、速度vpで等速で一直線上を動く。
ハリーは、点をつかまえることができるか。
出来るなら、YESと、その最短の時間および、そのときの点とハリーの位置を出力せよ。
出来ないならNOを出力せよ。
制約条件
n≦10000
vs≦vp
方針
二分探索。
各線分ごとに、時間tで点がつかまると仮定する。
時間tでの点の位置までにハリーが点にt以内で辿り着けるなら、hi=mid
そうでないならlo=midとして調べる区間を更新していく。
ソースコード
struct P{ double x,y,z; P operator+(const P &o)const{ P res=*this; res.x+=o.x; res.y+=o.y; res.z+=o.z; return res; } P operator-(const P &o)const{ P res=*this; res.x-=o.x; res.y-=o.y; res.z-=o.z; return res; } P operator*(double a){ P res=*this; res.x*=a; res.y*=a; res.z*=a; return res; } }; double d(const P &p){ return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); } P p[10000]; int n; void run() { cin>>n; n++; rep(i,n)cin>>p[i].x>>p[i].y>>p[i].z; double vp,vs,T=0; cin>>vp>>vs; P o; cin>>o.x>>o.y>>o.z; rep(i,n-1){ double lo=0,hi=1e9,mid; double t=d(p[i+1]-p[i])/vs; rep(it,100){ mid=(lo+hi)/2; P g=(p[i+1]-p[i])*(mid/t)+p[i]; if(d(g-o)<=vp*(mid+T))hi=mid; else lo=mid; } if(hi<t+EPS){ P g=(p[i+1]-p[i])*(hi/t)+p[i]; puts("YES"); printf("%.9f\n",hi+T); printf("%.9f %.9f %.9f\n",g.x,g.y,g.z); return; } T+=t; } cout<<"NO"<<endl; }