bzoj 4445 [SCOI2015] 小凸想跑步
Posted 117208
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于bzoj 4445 [SCOI2015] 小凸想跑步的主要内容,如果未能解决你的问题,请参考以下文章
[bzoj4445] [SCOI2015]小凸想跑步 (半平面交)
BZOJ4443[Scoi2015]小凸玩矩阵 二分+二分图最大匹配