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 }
View Code

 

以上是关于bzoj 4445 [SCOI2015] 小凸想跑步的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 4445: [Scoi2015]小凸想跑步

[bzoj4445] [SCOI2015]小凸想跑步 (半平面交)

BZOJ4443: [Scoi2015]小凸玩矩阵

BZOJ4443[Scoi2015]小凸玩矩阵 二分+二分图最大匹配

bzoj4443[Scoi2015]小凸玩矩阵 二分+二分图匹配

P4250 [SCOI2015]小凸想跑步