标签:des style color io os java ar strong for
2 100 2 1 0 10 0 0 3 -1 1 1 1 0 -1 1 2 1 0 10 0 0 3 -1 1 1 1 0 -1
6.39 -1
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double eps=1e-4; const double INF = 1e16; const int maxn = 50000+10; double sumL[maxn],sumR[maxn]; double Ts,Vr,Vs; int dcmp(double x) { if(fabs(x) < eps) return 0; else if(x < 0) return -1; else return 1; } struct Point{ double x,y; Point(double x0=0,double y0=0){ x=x0,y=y0; } friend bool operator < (Point a,Point b){ if(a.y!=b.y) return a.y<b.y; else return a.x<b.x; } }; Point Poly[maxn],cur,targ; int n; typedef Point Vector; double MinToLandT,ans; inline Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); } Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); } Vector operator / (Vector A,double p) { return Vector(A.x/p,A.y/p); } bool operator == (const Point &a,const Point &b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0 ; } inline double sqr(double x) { return x*x; } double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y; } double Length(Vector A){ return sqrt(Dot(A,A)); } double Angle(Vector A,Vector B){ return acos(Dot(A,B)/Length(A)/Length(B)); } double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; } Vector Rotate(Vector A,double rad){ return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); } double torad(double ang){ return ang/180.0*acos(-1.0); } void circle_cross_line(Point a,Point b,Point o,double r,Point ret[],int &num) { double x0 = o.x ,y0 = o.y; double x1 = a.x, y1 = a.y; double x2 = b.x, y2 = b.y; double dx = x2-x1, dy = y2-y1; double A = dx*dx+dy*dy; double B = 2*dx*(x1-x0) + 2*dy*(y1-y0); double C = sqr(x1-x0) + sqr(y1-y0)-sqr(r); double delta = B*B-4*A*C; num = 0; if( dcmp(delta) >= 0) { double t1 = (-B - sqrt(delta)) / (2*A); double t2 = (-B + sqrt(delta)) / (2*A); ret[num++] = Point(x1+t1*dx,y1+t1*dy); ret[num++] = Point(x1+t2*dx,y1+t2*dy); } } double DistanceToSegment(Point P,Point A,Point B){ if(A==B) return Length(P-A); Vector v1=B-A,v2=P-A,v3=P-B; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1); } double targetT(Point t,Point st) { if(dcmp(Length(t-targ)/Vs-Ts+MinToLandT) > 0) return INF; else return Length(t-st)/Vr+Length(t-targ)/Vs; } bool cmp(Vector a,Vector b) { if(dcmp(Cross(b , a)) > 0) return true; else if(dcmp(Cross(b,a))== 0) return abs(a.x) < abs(b.x); return false; } void input() { scanf("%lf%lf%lf",&Ts,&Vr,&Vs); scanf("%lf%lf",&cur.x,&cur.y); scanf("%lf%lf",&targ.x,&targ.y); scanf("%d",&n); for(int i = 0; i < n; i++) { scanf("%lf%lf",&Poly[i].x,&Poly[i].y); } Vector t1 = Poly[0]-Poly[1]; Vector t2 = Poly[2]-Poly[1]; if(dcmp(Cross(t1,t2)) > 0) { reverse(Poly,Poly+n); } MinToLandT = INF; for(int i = 0; i < n; i++) { MinToLandT = min(MinToLandT,DistanceToSegment(targ,Poly[i],Poly[(i+1)%n])*2/Vs); } } double thi_Search(Point p0 , Point p1, Point st){ Point l = p0 , r = p1; while(Length(l-r) > eps){ Point lmid = (l*2+r)/3 , rmid = (l+r*2)/3; if(targetT(lmid , st ) < targetT(rmid , st )) r = rmid; else l = lmid; } return targetT((l+r)/2 , st); } void init(int Lid,int Rid) { sumR[Rid] = Length(cur-Poly[Rid]); for(int i = (Rid+1)%n; i != Lid; i = (i+1)%n) { int before = (i-1+n)%n; sumR[i] = sumR[before] + Length(Poly[before]-Poly[i]); } sumL[Lid] = Length(cur-Poly[Lid]); for(int i = (Lid-1+n)%n; i != Rid; i = (i-1+n)%n) { int before = (i+1)%n; sumL[i] = sumL[before] + Length(Poly[before]-Poly[i]); } } bool PointOnSegment(Point o,Point a,Point b) {//o on segment (a,b) if(a.x > b.x) swap(a,b); return (dcmp(b.x-o.x) >= 0 && dcmp(o.x-a.x) >= 0); } void solve() { if(Ts < MinToLandT ) { puts("-1"); return; } Vector vec[maxn]; for(int i = 0; i < n; i++) { vec[i] = Poly[i]-cur; } sort(vec,vec+n,cmp); ans = INF; int Lid = 0,Rid = 0; Point L = vec[0]+cur,R; if(dcmp(Angle(vec[n-1],vec[n-2]))==0) R = vec[n-2]+cur; else R = vec[n-1]+cur; for(int i = 0; i < n; i++) { if(R==Poly[i]) Rid = i; if(L==Poly[i]) Lid = i; } init(Lid,Rid); for(int i = Lid; i != Rid; i = (i+1)%n) { Point o = targ; Point ret[2]; int num; double r = (Ts-MinToLandT)*Vs; Point a = Poly[i],b = Poly[(i+1)%n]; if(a.x > b.x) swap(a,b); circle_cross_line(a,b,o,r,ret,num); if(num==0) continue; if(num==1) { Point t = ret[0]; if(PointOnSegment(t,a,b)) { ans = min(ans,Length(t-cur)); } }else{ Point ep1,ep2; if(PointOnSegment(a,ret[0],ret[1])) { ep1 = a; }else{ ep1 = ret[0]; } if(PointOnSegment(b,ret[0],ret[1])) { ep2 = b; }else{ ep2 = ret[1]; } ans = min(ans,thi_Search(ep1 , ep2 , cur)); } } for(int i = Rid; i != Lid; i = (i+1)%n) { Point o = targ; Point ret[2]; int num; double r = (Ts-MinToLandT)*Vs; Point a = Poly[i],b = Poly[(i+1)%n]; if(a.x > b.x) swap(a,b); circle_cross_line(a,b,o,r,ret,num); double tmp1,tmp2; if(num==0) continue; if(num==1) { Point t = ret[0]; if(PointOnSegment(t,a,b)) { tmp1 = sumL[(i+1)%n] + Length(t-b); tmp2 = sumR[i]+Length(t-a); } }else{ Point ep1,ep2; if(PointOnSegment(a,ret[0],ret[1])) { ep1 = a; }else{ ep1 = ret[0]; } if(PointOnSegment(b,ret[0],ret[1])) { ep2 = b; }else{ ep2 = ret[1]; } tmp1 = sumL[(i+1)%n]/Vr+thi_Search(ep1 , ep2 , Poly[(i+1)%n]); tmp2 = sumR[i]/Vr+thi_Search(ep1 , ep2 , Poly[i]); } ans = min(tmp1,ans); ans = min(tmp2,ans); } ans += MinToLandT; if(ans >= INF) { puts("-1"); }else{ printf("%.2lf\n",ans); } } int main() { int ncase; cin >> ncase; while(ncase--) { input(); solve(); } return 0; }
标签:des style color io os java ar strong for
原文地址:http://blog.csdn.net/mowayao/article/details/39497505