1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| #include <bits/stdc++.h> using namespace std; #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) #define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++) #define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++) #define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--) #define DEBUG(x) cerr<<#x<<"="<<x<<endl #define all(x) (x).begin(),(x).end() #define cle(x) memset(x,0,sizeof(x)) #define lowbit(x) ((x)&-(x)) #define ll long long #define ull unsigned ll #define db long double #define pb push_back #define mp make_pair #define fi first #define se second inline int read() { int x=0; char ch=getchar(); bool f=0; for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1; for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48); return f?-x:x; } #define CASET fo(___,1,read())
const db eps=1e-8; const db pi=acos(-1.); const db inf=1e20; int sgn(db x) { if(fabs(x)<eps) return 0; if(x<0) return -1; return 1; } inline db sqr(db x){return x*x;}
struct Point{ db x,y; Point(){x=y=0;} Point(db _x,db _y){x=_x,y=_y;} void input(){scanf("%Lf%Lf",&x,&y);} friend inline bool operator==(Point A,Point B){return sgn(A.x-B.x)==0&&sgn(A.y-B.y)==0;} friend inline bool operator<(Point A,Point B){return sgn(A.x-B.x)==0?sgn(A.y-B.y)<0:A.x<B.x;} friend inline Point operator+(Point A,Point B){return Point(A.x+B.x,A.y+B.y);} friend inline Point operator-(Point A,Point B){return Point(A.x-B.x,A.y-B.y);} friend inline Point operator*(Point A,db k){return Point(A.x*k,A.y*k);} friend inline Point operator/(Point A,db k){return Point(A.x/k,A.y/k);} friend inline db operator^(Point A,Point B){return A.x*B.y-A.y*B.x;} friend inline db operator*(Point A,Point B){return A.x*B.x+A.y*B.y;} inline db len2(){return sqr(x)+sqr(y);} inline db len(){return sqrt(len2());} inline db angle(){return atan2(y,x);} }; struct Line{ Point s,e; Line(){} Line(Point _s,Point _e){s=_s,e=_e;} void adjust(){if(e<s) swap(e,s);} friend inline bool operator==(Line A,Line B){return A.s==B.s&&A.e==B.e;} inline db len(){return (e-s).len();} int relation(Point p) { int c=sgn((p-s)^(e-s)); return !c?3:(1+(c>0)); } bool parallel(Line v){return sgn((e-s)^(v.e-v.s))==0;} int linecrossline(Line v) { if((*this).parallel(v)) return v.relation(s)==3; return 2; } Point Intersection(Line v) { db a1=(v.e-v.s)^(s-v.s); db a2=(v.e-v.s)^(e-v.s); return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1)); } }; const int N=200010; int n,m; Point a[N],b[N]; db sum,s[N]; Line li[N];
inline db ask(int l,int r) { if(l<r) return s[r-1]-s[l]; else return s[n-1]-s[l]+(r?s[r-1]:0); }
int main() { n=read(); m=read(); ff(i,0,n) a[i].input(); ff(i,0,m) b[i].input(); Line now=Line(b[0],b[1]); ff(i,0,n) li[i]=Line(a[i],a[(i+1)%n]),sum+=li[i].len(); ff(i,0,n) s[i]=li[i].len()+(i?s[i-1]:0.0); int l,r; ff(i,0,n) if(now.relation(a[i])==1&&now.relation(a[(i+1)%n])!=1) { l=i; break; } ff(i,0,n) if(now.relation(a[i])==2&&now.relation(a[(i+1)%n])!=2) { r=i; break; } db ans=(ask(l,r)+(now.Intersection(li[l])-a[(l+1)%n]).len()+(now.Intersection(li[r])-a[r]).len())/sum*now.len(); ff(i,1,m) { now=Line(b[i],b[(i+1)%m]); for(;;) if(now.relation(a[l])!=2&&now.relation(a[(l+1)%n])!=1) break; else l=(l+1)%n; for(;;) if(now.relation(a[r])!=1&&now.relation(a[(r+1)%n])!=2) break; else r=(r+1)%n; ans+=(ask(l,r)+(now.Intersection(li[l])-a[(l+1)%n]).len()+(now.Intersection(li[r])-a[r]).len())/sum*now.len(); } printf("%.12Lf",ans); return 0; }
|