【蒙特卡洛模拟】EOJ Monthly 2018.12 B. 清点星辰 3658

EOJ Monthly 2018.12 B. 清点星辰

3658. 清点星辰

描述统计讨论区

单测试点时限: 2.0 秒

内存限制: 512 MB

“夜里,
你要抬头仰望满天的星星。
我那颗实在太小了,
我都没法指给你看它在哪儿。”

 

这样倒也好,我的星星,对你来说就是满天星星中的一颗。

所以,你会爱这满天的星星…所有的星星都会是你的朋友。

即使只能通过狭小的洞口,在楼宇的夹缝中仰望布满星辰的天空,你还是无法割舍对它的期待。

星星数不胜数,但你还是不厌其烦地清点他们。日复一日,终于在今天,你把他们都数清楚了。

于是你又开始找别的事情做了。你开始计算他们两两之间的最近距离。

你仰望星空的洞口是一个 1×1 的正方形,每天,星辰的位置都会发生变化,具体地说,每天都会有 n 个星辰随机地散落在这个正方形内的某个坐标上(每个点横纵坐标满足独立同分布 U(0,1))。

每天的距离都在变化,所以现在你只想知道他们两两之间最近距离的期望是多少。

输入

输入一个整数 n (2≤n≤109) ,表示星辰的数量。

输出

一行一个小数,输出答案。绝对误差在 10−3 内会被视为正确。

样例

input

2

output

0.521405

input

3

output

0.3055302430

提示

对于某连续性随机变量 X,若其取值范围为 Ω,其概率密度函数为 p(x),则其期望定义为 E(X)=∫Ωxp(x)。若要求关于 X 的函数 f(X) 的期望,则 E(f(X))=∫Ωf(x)p(x)。

该式子可以在多变量上进行推广,如果有两个随机变量 X, Y,则关于 X,Y 的函数 f(X,Y) 的期望可以定义为 E(f(X,Y))=∫Ωf(x,y)p(x,y),其中 p(x,y) 是 x,y 的联合概率密度函数。在 X 和 Y 独立时,p(x,y)=p(x)p(y)

在本题中,所有变量的概率密度函数都是 p(x)=1,0<x<1。故所求式可以写为:

∫10∫10⋯∫102nmin1≤i<j≤n(xi−xj)2+(yi−yj)2−−−−−−−−−−−−−−−−−√ dx1dy1dx2dy2⋯dxndyn

在 n=2 时,该式可以化简为:

 

∫10∫10∫10∫10(x1−x2)2+(y1−y2)2−−−−−−−−−−−−−−−−−−√ dx1dy1dx2dy2

求出该积分的值约为 0.521405。

在 n>2​ 的情形下,由于式子中有 min,积分式十分复杂,很有可能没有解析解。在定积分不可行的情况下,可以采用数值逼近的方法近似计算给定的定积分值,这种方法称为数值积分。借助于电子计算设备,数值积分可以快速而有效地计算复杂的积分。数值积分常用的方法包括矩形法、辛普森积分法等。更多有关数值积分的数学原理和算法介绍,读者可以自行阅读维基百科

#include <bits/stdc++.h>
using namespace std;
double dx[1000],dy[1000];
int main()
{
    srand(0);  //时间种子防止被卡
    int n;
    scanf("%d",&n);
    if(n>1000) //要是n太大,那么最近两个点距离一定<0.0001,因为误差保持在0.001,那么朱姐输出0就好了
    {
        printf("0.0000000000\n");
        return 0;
    }
    int k=1e8/n/n; //因为每次都是n^2,所以最多k轮
    double ans=0.0;
    for(int i=1;i<=k;i++)  
    {
        double minn=1e18;
        for(int j=1;j<=n;j++)
        {
            dx[j]=1.0*(rand()%32767)/32766; //得到0-1的小数,模拟坐标
            dy[j]=1.0*(rand()%32767)/32766;
            for(int p=1;p<j;p++)
            {
                minn=min(minn,sqrt((dx[j]-dx[p])*(dx[j]-dx[p])+(dy[j]-dy[p])*(dy[j]-dy[p]))); //计算每轮模拟后最小的距离
            }
        }
        ans+=minn;
    }
    printf("%.10f\n",ans/k);//得到平均答案

    return 0;
}

 

蒙特卡罗方法(Monte Carlo method),也称统计模拟方法,是一种数值计算方法。是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法。

通常蒙特卡罗方法:因所求解的问题本身具有内在的随机性,借助计算机的运算能力可以直接模拟这种随机的过程。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值