bzoj 4445 [SCOI2015] 小凸想跑步
题目大意:一个凸包,随机一个点使得其与前两个点组成的面积比与其他相邻两个点组成的面积小的概率
根据题意列方程,最后求n条直线的交的面积与原凸包面积的比值
1 #include<bits/stdc++.h> 2 #define maxn 100010 3 #define eps 1e-10 4 using namespace std; 5 double ans,S1,S2; 6 struct P{ 7 double x,y; 8 P(double a=0,double b=0){x=a,y=b;} 9 }; 10 struct L{ 11 P a,b; 12 double ang; 13 }; 14 int sgn(double x){ 15 return (x>eps)-(x<-eps); 16 } 17 P operator - (P a,P b){ 18 return P(a.x-b.x,a.y-b.y); 19 } 20 double operator * (P a,P b){ 21 return a.x*b.y-a.y*b.x; 22 } 23 bool operator < (L a,L b){ 24 if(sgn(a.ang-b.ang)!=0)return a.ang<b.ang; 25 return (a.a-b.a)*a.b<0; 26 } 27 int n; 28 P s[maxn]; 29 L l[maxn],q[maxn];P p[maxn]; 30 int h,r,tot,cnt; 31 L get_line(P A,P B,P C,P D){ 32 L l; 33 double a=-A.y-D.y+B.y+C.y; 34 double b=-B.x-C.x+A.x+D.x; 35 double c=-A.x*B.y-D.x*C.y+B.x*A.y+C.x*D.y; 36 l.b=P(b,-a); 37 if(sgn(a)!=0)l.a=P(-c/a,0); 38 else l.a=P(0,-c/b); 39 return l; 40 } 41 void get_line(){ 42 for(int i=2;i<=n;++i) 43 l[++cnt]=get_line(s[1],s[2],s[i],s[i+1]); 44 for(int i=1;i<=n;++i){ 45 l[++cnt].a=s[i]; 46 l[cnt].b=s[i+1]-s[i]; 47 } 48 for(int i=1;i<=cnt;++i) 49 l[i].ang=atan2(l[i].b.y,l[i].b.x); 50 } 51 P inter(L a,L b){ 52 P p=b.a-a.a; 53 double t=(p*b.b)/(a.b*b.b); 54 P ans; 55 ans.x=a.a.x+a.b.x*t; 56 ans.y=a.a.y+a.b.y*t; 57 return ans; 58 } 59 bool jud(L a,L b,L c){ 60 P p=inter(a,b); 61 return (p-c.a)*c.b>0; 62 } 63 void get_Point(){ 64 sort(l+1,l+cnt+1);tot=1; 65 for(int i=2;i<=cnt;++i) 66 if(sgn(l[i].ang-l[i-1].ang)!=0) 67 l[++tot]=l[i]; 68 cnt=tot;tot=0,h=1; 69 q[++r]=l[1];q[++r]=l[2]; 70 for(int i=3;i<=cnt;++i){ 71 if(sgn(q[r].b*q[r-1].b)==0)return; 72 if(sgn(q[h].b*q[h+1].b)==0)return; 73 while(h<r&&jud(q[r-1],q[r],l[i]))r--; 74 while(h<r&&jud(q[h+1],q[h],l[i]))h++; 75 q[++r]=l[i]; 76 } 77 while(h<r&&jud(q[r-1],q[r],q[h]))r--; 78 while(h<r&&jud(q[h+1],q[h],q[r]))h++; 79 q[r+1]=q[h]; 80 for(int i=h;i<=r;++i) 81 p[++tot]=inter(q[i],q[i+1]); 82 p[++tot]=p[1]; 83 } 84 double get_S(P a[],int cnt){ 85 double ans=0; 86 if(cnt<3)return 0; 87 for(int i=1;i<cnt;++i){ 88 ans+=a[i]*a[i+1]; 89 } 90 ans=fabs(ans/2); 91 return ans; 92 } 93 void init(){ 94 scanf("%d",&n); 95 for(int i=1;i<=n;++i){ 96 int x,y;scanf("%d%d",&x,&y); 97 s[i].x=x;s[i].y=y; 98 } 99 s[n+1]=s[1]; 100 } 101 void work(){ 102 get_line(); 103 get_Point(); 104 S1=get_S(s,n+1); 105 S2=get_S(p,tot); 106 ans=S2/S1; 107 printf("%.4lf",ans); 108 } 109 int main(){ 110 init(); 111 work(); 112 return 0; 113 }