【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
 2 #include
 3 #include
 4 #include
 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)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(L1&&!onleft(hp[R],hp[R-1],l[i])) R--;
54         while(L1&&!onleft(hp[L+1],hp[L+2],l[i])) L++;
55         hp[++R] = l[i];
56     }
57     while(L1&&!onleft(hp[R],hp[R-1],hp[L+1])) R--; hp[++R] = hp[L+1];
58     m=0;for(int i=L+1;i1]); 
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\n",i,v.x,v.y);
73     }
74     half();
75     lf ansA = 0,ansB = 0;
76     for(int i=2;i1]-py[i])*(py[i]-py[1]); ansA = fabs(ansA);
77     for(int i=2;i1]-p[i])*(p[i]-p[1]); ansB = fabs(ansB);//
78     printf("%.4Lf",ansA/ansB);
79     return 0;
80 }//by tkys_Austin;

 

 

 

转载于:https://www.cnblogs.com/Paul-Guderian/p/8693022.html

你可能感兴趣的:(数据结构与算法)