题意
这题显然是暴推式子。
考虑下图:

\(S_{ABP}<S_{CDP}\iff \vec{AB}*\vec{AP}<\vec{CD}*\vec{CP}\)
暴力展开可得:
\((x_b-x_a,y_b-y_a)\times(x_p-x_a,y_p-y_a)<(x_d-x_c,y_d-y_c)\times(x_p-x_c,y_p-y_c)\)
\((x_b-x_a)*(y_p-y_a)-(y_b-y_a)*(x_p-x_a)<(x_d-x_c)*(y_p-y_c)-(y_d-y_c)*(x_p-x_c)\)
化简得:
\(x_p(y_a-y_b+y_d-y_c)+y_p(x_b-x_a+x_c-x_d)+((x_ay_b-x_by_a)-(x_cy_d-x_dy_c))<0\)
这是条直线,我们用半平面交即可概率就是合法面积/总面积。
code:
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; const double eps=1e-10; const double inf=1e12; int n,m; double sum,ans; struct Point { double x,y; inline double len(){return sqrt(x*x+y*y);} Point operator+(const Point a)const{return (Point){x+a.x,y+a.y};} Point operator-(const Point a)const{return (Point){x-a.x,y-a.y};} Point operator*(const double k){return (Point){x*k,y*k};} Point operator/(const double k){return (Point){x/k,y/k};} double operator*(const Point a)const{return x*a.y-y*a.x;} double operator&(const Point a)const{return x*a.x+y*a.y;} }p[maxn],a[maxn<<1]; inline int dcmp(double x) { if(fabs(x)<=eps)return 0; return x<0?-1:1; } inline Point get(Point a,Point b){return b-a;} struct Line { Point p,v;double theta; bool operator<(const Line& a)const { return !dcmp(theta-a.theta)?dcmp(get(p,v)*get(p,a.v))<0:dcmp(theta-a.theta)<0; } }line[maxn<<1],q[maxn<<1]; inline Point getpoint(Line l1,Line l2) { Point p1=l1.p,v1=l1.v,p2=l2.p,v2=l2.v; v1=get(p1,v1),v2=get(p2,v2); Point u=get(p1,p2); return p2+v2*(u*v1)/(v1*v2); } inline bool check(Line a,Line b,Line c) { Point p=getpoint(a,b); return dcmp(get(c.p,c.v)*get(c.p,p))<=0; } inline void solve() { for(int i=1;i<=m;i++)line[i].theta=atan2(line[i].v.y-line[i].p.y,line[i].v.x-line[i].p.x); sort(line+1,line+m+1); int cnt=0;line[0].theta=inf; for(int i=1;i<=m;i++)if(line[i].theta!=line[i-1].theta)line[++cnt]=line[i]; m=cnt; int l,r; q[l=r=1]=line[1];q[++r]=line[2]; for(int i=3;i<=m;i++) { while(l<r&&check(q[r-1],q[r],line[i]))r--; while(l<r&&check(q[l],q[l+1],line[i]))l++; q[++r]=line[i]; } while(l<r&&check(q[r-1],q[r],q[l]))r--; while(l<r&&check(q[l],q[l+1],q[r]))l++; cnt=0; q[r+1]=q[l]; for(int i=l;i<=r;i++)a[++cnt]=getpoint(q[i],q[i+1]); a[cnt+1]=a[1]; for(int i=1;i<=cnt;i++)ans+=a[i]*a[i+1]; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); p[n+1]=p[1]; for(int i=1;i<=n;i++) { line[++m]=(Line){p[i],p[i+1],0}; sum+=p[i]*p[i+1]; } for(int i=2;i<=n;i++) { double a,b,c; a=p[1].y-p[2].y-p[i].y+p[i+1].y; b=p[2].x-p[1].x+p[i].x-p[i+1].x; c=p[1].x*p[2].y-p[2].x*p[1].y-p[i].x*p[i+1].y+p[i+1].x*p[i].y; Point p; if(!dcmp(b))p=(Point){-c/a,0}; else p=(Point){0,-c/b}; line[++m]=(Line){p,p+(Point){-b,a},0}; } solve(); printf("%.4lf",ans/sum); return 0; }
来源:https://www.cnblogs.com/nofind/p/12244699.html