• 【bzoj4445 scoi2015】小凸想跑步


    题目描述

    小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏。

    操场是个凸 nn 边形, nn 个顶点按照逆时针从 00  n - 1n1 编号。现在小凸随机站在操场中的某个位置,标记为 pp 点。将 pp点与 nn 个顶点各连一条边,形成 nn 个三角形。如果这时 pp 点, 00 号点, 11 号点形成的三角形的面 积是 nn 个三角形中最小的一个,小凸则认为这是一次正确站位。

    现在小凸想知道他一次站位正确的概率是多少。

    输入输出格式

    输入格式:

     11 行包含 11 个整数 nn , 表示操场的顶点数和游戏的次数。

    接下来有 nn 行,每行包含 22 个整数 x_i, y_ixi,yi ,表示顶点的坐标。

    输入保证按逆时针顺序输入点,所有点保证构成一个凸多边形。所有点保证不存在三点共线。

    输出格式:

    输出 11 个数,正确站位的概率,保留 44 位小数。

    说明

    对于 3030 % 的数据, 3 leq n leq 4, 0 leq x, y leq 103n4,0x,y10

    对于 100100 % 的数据, 3 leq n leq 10^5, -10^9 leq x, y leq 10^93n105,109x,y109

    题意:已经很清楚了!

    题解:

    ①你可以设坐标为x,y画一下柿子可以做,网上这类做法主流;

    ②下面是大米兔的非主流做法:

     

    肯定是用合法的面积/总面积,AB是P0P1的话,合法的应该是OE分割的的靠近

    AB的半部分,如果求出所有的OE就可以求出合法的面积;OE是什么呢?定义是

    在OE上的任意一点P,$S_{PDC}=S_{PAB}$,E的方向可以直接由A'D'的中点

    获得,结合交点O可求出OE,这样复杂度OK;实现也是半平面交而已;

    ③注意n变形的n条边也要加进去!

     

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 using namespace std;
     6 const double eps = 1e-20;
     7 const int N=200010;
     8 typedef long double lf;
     9 int n,m,tot;
    10 char gc(){
    11     static char *p1,*p2,s[1000000];
    12     if(p1==p2) p2=(p1=s)+fread(s,1,1000000,stdin);
    13     return (p1==p2)?EOF:*p1++;
    14 }
    15 int rd(){
    16     int x=0,f=1; char c=gc();
    17     while(c<'0'||c>'9') {if(c=='-') f=-1;c=gc();}
    18     while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-'0';c=gc();}
    19     return x*f;
    20 }
    21 int dcmp(lf x){return fabs(x)<eps?0:x<0?-1:1;/*x==0?0:x<0?-1:1;*/}
    22 struct point{lf x,y;point(){};point(lf x,lf y):x(x),y(y){};}p[N],py[N];
    23 struct line{point A,B; lf ang;line(){}line(point A,point B):A(A),B(B){ang=atan2(B.y-A.y,B.x-A.x);}}hp[N],l[N];
    24 point operator -(const point&A,const point&B){return point(A.x-B.x,A.y-B.y);}
    25 point operator +(const point&A,const point&B){return point(A.x+B.x,A.y+B.y);}///
    26 lf operator *(const point&A,const point&B){return A.x*B.y-A.y*B.x;}
    27 lf operator ^(const point&A,const point&B){return A.x*B.x+A.y*B.y;}
    28 point operator *(const point&A,lf t){return point(A.x*t,A.y*t);}
    29 point operator /(const point&A,lf t){return point(A.x/t,A.y/t);}
    30 bool operator <(const line&l1,const line&l2){
    31     int d = dcmp(l1.ang-l2.ang);
    32     return (!d)?(dcmp((l1.B-l1.A)*(l2.A-l1.A))<0):(d<0);
    33 }///
    34 point inter(line l1, line l2){
    35     if(!dcmp(l1.ang-l2.ang)) return (l1.A+l2.A)/2;
    36     lf t,k1,k2;
    37     k1 = (l2.B-l2.A)*(l1.A-l2.A);
    38     k2 = (l1.B-l1.A)*(l2.B-l2.A);
    39     t = k1 / k2;
    40     return l1.A + (l1.B-l1.A)*t;
    41 }//////
    42 bool onleft(line l1,line l2,line l){
    43     point ip = inter(l1,l2);
    44     return dcmp((l.B-l.A)*(ip-l.A))>0;
    45 }//
    46 lf len(point A){return sqrt(A.x*A.x+A.y*A.y);}
    47 void half(){///
    48     sort(l+1,l+tot+1);
    49     int tmp = tot,tot = 0,L=0,R=0;
    50     for(int i=1;i<=tmp;i++){if(i==1||dcmp(l[i-1].ang-l[i].ang)) l[++tot]=l[i];}    
    51     hp[++R] = l[1]; hp[++R] = l[2];
    52     for(int i=3;i<=tot;i++){
    53         while(L<R-1&&!onleft(hp[R],hp[R-1],l[i])) R--;
    54         while(L<R-1&&!onleft(hp[L+1],hp[L+2],l[i])) L++;
    55         hp[++R] = l[i];
    56     }
    57     while(L<R-1&&!onleft(hp[R],hp[R-1],hp[L+1])) R--; hp[++R] = hp[L+1];
    58     m=0;for(int i=L+1;i<R;i++) py[++m]=inter(hp[i],hp[i+1]); 
    59 }
    60 point calc(point A,point B){return (A+B)/2;}
    61 int main()
    62 {    freopen("bzoj4445.in","r",stdin);
    63     freopen("bzoj4445.out","w",stdout);
    64     n=rd(); 
    65     for(int i=1;i<=n;i++) p[i].x=rd(),p[i].y=rd(); p[n+1] = p[1];
    66     for(int i=1;i<=n;i++) l[++tot] = line(p[i],p[i+1]);///
    67     for(int i=2;i<=n;i++){
    68         point ip = inter(line(p[i+1],p[i]),line(p[1],p[2])),v;
    69         if(dcmp((p[2]-p[1])*(p[i+1]-p[i]))>=0) 
    70         v=calc(p[1]-p[2],p[i+1]-p[i]),l[++tot]=line(ip,ip+v);
    71         else v=calc(p[2]-p[1],p[i]-p[i+1]),l[++tot]=line(ip+v,ip);//////
    72         //printf("%d %.4lf %.4lf
    ",i,v.x,v.y);
    73     }
    74     half();
    75     lf ansA = 0,ansB = 0;
    76     for(int i=2;i<m;i++) ansA+=(py[i+1]-py[i])*(py[i]-py[1]); ansA = fabs(ansA);
    77     for(int i=2;i<n;i++) ansB+=(p[i+1]-p[i])*(p[i]-p[1]); ansB = fabs(ansB);//
    78     printf("%.4Lf",ansA/ansB);
    79     return 0;
    80 }//by tkys_Austin;

     

     

  • 相关阅读:
    Windows群集安装
    iSCSI配置流程
    StarWind的安装配置
    安装SQL Server 2012 『企业中文版』
    计划安装SQL Server2012需求详细
    Max Degree of Parallelism最大并行度配置
    最佳的MongoDB客户端管理工具
    自学站点地图
    一个解决方案下多个项目时,怎么调试1个项目时不启动其他项目
    如何创建一个https的站点(超简单) 以及 IIS7.5绑定Https域名
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/8693022.html
Copyright © 2020-2023  润新知