好神的几何题
把一个点不动作为参照物 然后就变成了只有一个点在动
画出来就是这样
然后就是求 一个点到两组平行线段的距离最小值
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double ld;inline ld sqr(ld x){ return x*x; }
inline int sgn(ld x){if (fabs(x)<1e-8) return 0;return x<0?-1:1;
}struct PP{ld x,y;PP(ld x=0,ld y=0):x(x),y(y) { }bool read() { double _x,_y; if (scanf("%lf%lf",&_x,&_y)==-1) return 0; x=_x; y=_y; return 1; }ld dist() { return sqrt(x*x+y*y); }PP operator - () { return PP(-x,-y); }friend PP operator + (PP A,PP B) { return PP(A.x+B.x,A.y+B.y); }friend PP operator - (PP A,PP B) { return PP(A.x-B.x,A.y-B.y); }friend PP operator * (PP A,ld B) { return PP(A.x*B,A.y*B); }friend PP operator / (PP A,ld B) { return PP(A.x/B,A.y/B); } friend ld operator * (PP A,PP B) { return A.x*B.x+A.y*B.y; }friend ld cross(PP A,PP B) { return A.x*B.y-A.y*B.x; }friend ld dist(PP A,PP B) { return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y)); }
};inline ld calc(PP p,PP A,PP B){if (sgn(A.x-B.x)==0 && sgn(A.y-B.y)==0)return dist(p,A);if (sgn((p-A)*(B-A))>0 && sgn((p-B)*(A-B))>0)return fabs(cross(p-A,B-A))/dist(A,B);return min(dist(A,p),dist(B,p));
}inline ld calc(PP p,PP A,PP B,PP D){int L=0,R=1<<28,m1,m2; ld f1,f2;while (R-L>12){m1=(L+L+R)/3; m2=(L+R+R)/3;f1=calc(p,A+D*m1,B+D*m1);f2=calc(p,A+D*m2,B+D*m2);if (f1<f2)R=m2;elseL=m1;}ld ret=1e20;for (int i=L;i<=R;i++)ret=min(ret,calc(p,A+D*i,B+D*i));return ret;
}ld vw,vt;
PP w0,w1,t0,t1;
ld mind,maxd;inline void Solve(){ld Time=dist(t0,t1)/vt;PP tg=(t1-t0)/dist(t0,t1)*vt;PP wg=(w1-w0)/dist(w0,w1)*vw;PP p1=t0+(tg-wg)*Time;PP p2=p1+(-tg-wg)*Time;ld d1=calc(w0,t0,p1,p2-t0);ld d2=calc(w0,p1,p2,p2-t0);ld d=min(d1,d2);if (sgn(d-maxd)>0)printf("Miss\n");else if (sgn(mind-d)>0)printf("Dangerous\n");elseprintf("Perfect\n");
}int main(){freopen("t.in","r",stdin);freopen("t.out","w",stdout);while (w0.read()){w1.read(); scanf("%lf",&vw);t0.read(); t1.read(); scanf("%lf",&vt);scanf("%lf%lf",&mind,&maxd);Solve();}return 0;
}