zoukankan      html  css  js  c++  java
  • 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html

    题目传送门 - 2018牛客多校赛第三场 I

    题意

      在一个给定的三角形内部随机选择 $n$ 个点,问这些点构成的凸包的期望顶点数。

      $3leq nleq 10$

    题解

      首先证明一个结论,对于任意三角形,随机撒 $n$ 个点的期望点数相同。

      简单口胡:考虑任意拉扯三角形,三角形内部多边形的凸性都不会改变。

      所以,我们只需要随便选择一个三角形,然后随机选点很多次,建出凸包,得到顶点数,然后算一算平均值,就可以得到答案了。

      注意随机选点次数至少好几亿吧。

      我赛后代码跑了大约 25 分钟才跑出来。

    代码1 - 打表

    %:pragma GCC optimize("Ofast")
    %:pragma GCC optimize("inline")
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=20;
    int n;
    struct Point{
    	int x,y;
    	Point(){}
    	Point(int _x,int _y){
    		x=_x,y=_y;
    	}
    }P[N],O;
    LL cross(Point a,Point b,Point c){
    	return 1LL*(b.x-a.x)*(c.y-a.y)-1LL*(c.x-a.x)*(b.y-a.y);
    }
    int Drand(){
    	return (int)((((rand()&32767)<<10)+(rand()&1024))&33554431);
    }
    LL sqr(int x){
    	return 1LL*x*x;
    }
    LL dis(Point a,Point b){
    	return sqr(a.x-b.x)+sqr(a.y-b.y);
    }
    bool cmp_O(Point a,Point b){
    	if (a.y==b.y)
    		return a.x<b.x;
    	return a.y<b.y;
    }
    bool cmp_Angle(Point a,Point b){
    	LL c=cross(O,a,b);
    	if (c==0)
    		return dis(O,a)<dis(O,b);
    	return c>0;
    }
    int st[N],top;
    int Convex(){
    	for (int i=2;i<=n;i++)
    		if (!cmp_O(P[1],P[i]))
    			swap(P[1],P[i]);
    	O=P[1];
    	sort(P+2,P+n+1,cmp_Angle);
    	top=0;
    	st[++top]=1,st[++top]=2;
    	for (int i=3;i<=n;i++){
    		while (top>=2&&cross(P[st[top-1]],P[st[top]],P[i])<=0)
    			top--;
    		st[++top]=i;
    	}
    	return top;
    }
    int main(){
    freopen("list.txt","w",stdout);
    	srand(time(NULL));
    for (int i=3;i<=10;i++){
    	n=i;
    	int tot=200000000,ttt=tot;
    	int ans=0;
    	while (tot--){
    		for (int i=1;i<=n;i++)
    			while (1){
    				P[i]=Point(Drand(),Drand());
    				if (P[i].y<=P[i].x)
    					break;
    			}
    		ans+=Convex();
    	}
    	printf("%.6lf
    ",((double)ans)/ttt);
    }
    	return 0;
    }
    

      

    代码2 - AC 代码

    #include <bits/stdc++.h>
    using namespace std;
    double ans[11]={
    0,0,0,
    3.000000,
    3.666719,
    4.166715,
    4.566691,
    4.899998,
    5.185735,
    5.435731,
    5.657986
    };
    int main(){
    	int n;
    	for (int i=1;i<=7;i++)
    		scanf("%d",&n);
    	printf("%.6lf",ans[n]);
    	return 0;
    }
    

      

  • 相关阅读:
    Linux IO接口 监控 (iostat)
    linux 防火墙 命令
    _CommandPtr 添加参数 0xC0000005: Access violation writing location 0xcccccccc 错误
    Visual Studio自动关闭
    Linux vsftpd 安装 配置
    linux 挂载外部存储设备 (mount)
    myeclipse 9.0 激活 for win7 redhat mac 亲测
    英文操作系统 Myeclipse Console 乱码问题
    Linux 基本操作命令
    linux 查看系统相关 命令
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html
Copyright © 2011-2022 走看看