First, the speed is subtracted, and a is moved and B does not move, and if the velocity is 0, it will never intersect.
Enumerates each point of a and each segment of B, calculating the time at which the three points collinear.
The time is sorted, three points are made for each interval, and the intersection area is calculated using half-plane intersection.
Pay attention to the case where the intersection area is 0 but there are intersections.
Time complexity $o (N^4\LOG^2N) $.
#include <cstdio> #include <algorithm> #include <cmath>using namespace Std;const int N=200;const Double Eps=1e-9;int SGN (double x) {if (x<-eps) return-1; if (x>eps) return 1; return 0;} int n,m,cnt,i,j,vx,vy,x,y;double q[n],ans=-1,anst;struct vec{double x, y; Vec () {x=y=0;} VEC (double _x,double _y) {x=_x,y=_y;} Vec operator+ (Vec v) {return VEC (X+V.X,Y+V.Y);} Vec operator-(Vec v) {return VEC (X-V.X,Y-V.Y);} Vec operator* (double v) {return VEC (X*V,Y*V);} Vec operator/(double v) {return VEC (x/v,y/v);} Double operator* (Vec v) {return x*v.x+y*v.y;} Double Len () {return hypot (x, y);} Double Len_sqr () {return x*x+y*y;}} A[n],b[n],c[n],v,o;double Cross (VEC A,vec b) {return a.x*b.y-a.y*b.x;} BOOL Point_on_segment (VEC P,vec A,vec b) {return sgn (Cross (B-A,P-A)) ==0&&SGN ((p-a) * (p-b)) <=0;} int has_intersection (VEC a,vec b,vec P,vec q) {int d1=sgn (cross (B-A,P-A)), D2=SGN (Cross (b-a,q-a)), D3=SGN (Cross (q-p,a -p)), D4=SGN (Cross (q-p,b-p)); if (d1*d2<0&&d3*d4<0) reTurn 1; if (D1==0&&point_on_segment (p,a,b)) return-1; if (D2==0&&point_on_segment (q,a,b)) return-1; if (D3==0&&point_on_segment (a,p,q)) return-1; if (D4==0&&point_on_segment (b,p,q)) return-1; return 0;} int line_intersection (VEC a,vec b,vec P,vec q,vec&o) {double U=cross (p-a,q-p), D=cross (b-a,q-p); if (SGN (D) ==0) return 0; o=a+ (b-a) * (U/D); return 1;} struct p{double x, y; P () {x=y=0;} P (double _x,double _y) {x=_x,y=_y;} P (Vec p) {x=p.x,y=p.y;} P operator-(const p&a) Const{return P (X-A.X,Y-A.Y);} P operator+ (const p&a) Const{return P (X+A.X,Y+A.Y);} P operator* (double A) Const{return p (x*a,y*a);}}; namespace Halfplane{p p[n],a[n];struct l{P p,v;double A; L () {} l (P _p,p _v) {p=_p,v=_v;} BOOL operator< (const L&B) Const{return A<B.A;} void Cal () {a=atan2 (v.y,v.x);}} Line[n],q[n];int cl;double Cross (const p&a,const p&b) {return a.x*b.y-a.y*b.x;} void Newl (const p&a,const p&b) {line[++cl]=l (a,b-a);} BOOL Left (const P&P,CONST l&l) {return cross (L.V,P-L.P) >0;} P POS (const l&a,const l&b) {p X=A.P-B.P; Double T=cross (b.v,x)/cross (A.V,B.V); return a.p+a.v*t;} Double Halfplane () {for (int i=1;i<=cl;i++) line[i].cal (); Sort (line+1,line+cl+1); int h=1,t=1; Q[1]=LINE[1]; for (int i=2;i<=cl;i++) {while (H<t&&!left (P[t-1],line[i])) t--; while (H<t&&!left (p[h],line[i))) h++; if (Fabs (Q[T].V,LINE[I].V) <eps) Q[t]=left (Q[t].p,line[i])? Q[t]:line[i]; else Q[++t]=line[i]; if (h<t) P[t-1]=pos (q[t],q[t-1]); } while (H<t&&!left (P[t-1],q[h])) t--; P[t]=pos (Q[t],q[h]); if (t-h<=1) return-1; Double ans=0; for (int i=h;i<t;i++) Ans+=cross (p[i],p[i+1]); Return Ans+cross (P[t],p[h]);}} Double cal (double T) {if (!SGN (t)) return-1; Double ret=-1; int i,j; for (i=0;i<=n;i++) c[i]=a[i]+ (v*t); for (i=0;i<n;i++) for (j=0;j<m;j++) if (Has_intersection (c[i],c[i+1],b[j],b[j+1))) ret=0; halfplane::cl=0; for (i=0;i<n;i++) HALFPLANE::NEWL (P (c[i+1]), p (c[i])); for (i=0;i<m;i++) HALFPLANE::NEWL (P (b[i+1]), P (B[i])); Ret=max (Ret,halfplane::halfplane ()); if (SGN (Ret-ans) >0| | (SGN (Ret-ans) ==0&&t<anst)) ans=ret,anst=t; return ret;} int main () {scanf ("%d", &n); for (i=0;i<n;i++) scanf ("%lf%lf", &a[i].x,&a[i].y); a[n]=a[0]; scanf ("%d%d", &vx,&vy); scanf ("%d", &m); for (i=0;i<m;i++) scanf ("%lf%lf", &b[i].x,&b[i].y); b[m]=b[0]; scanf ("%d%d", &x,&y); Vx-=x,vy-=y; if (!vx&&!y) return puts ("never"), 0; V=vec (Vx,vy); q[cnt=1]=0; for (i=0;i<n;i++) for (j=0;j<m;j++) if (Line_intersection (a[i],a[i]+v,b[j],b[j+1],o)) q[++cnt]= (O-a[i]). Len ()/ V.len (); Sort (q+1,q+cnt+1); for (i=1;i<=cnt;i++) Cal (Q[i]); for (i=1;i<cnt;i++) {double l=q[i],r=q[i+1]; while (L+1e-6<r) {double len= (r-l)/3,m1=l+len,m2=r-len; Double F1=cal (M1), f2=cal (m2); if (SGN (F1-F2) >=0) R=m2;else l=m1; }} if (ans<-0.5) puts ("never"), Else printf ("%.6f", anst); return 0;}
BZOJ4107: [Wf2015]asteroids