做这道题之前首先了解一下数学期望是要求概率的,根据大数定律这个值并不是一个准确定值,而是无限接近于事情发生概率的最接近值。
对于本题来说,两次就取遍所有球星的概率为 1/n,三次取遍所有球星的概率为 1/n^2…
以此类推,k次取遍所有球星的概率为 1/n^k-1。
则**E(n)=2/n+3/n2+4/n3+…。**这个的趋近规律可以总结为:
E(n)=n/n+n/n-1+…+n/1。
规律已总结出,接下来这个题就变成了一个简单的分数相加大模拟。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
void read(ll &x)
{
x=0;int p=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') p=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
x*=p;
}// 读入优化自动忽略。
ll gcd(ll x,ll y)
{
if(y>x)
{
int tmp;
tmp=x;
x=y;
y=tmp;
}
if(x%y==0)
{
return y;
}
else gcd(y,x%y);
}// 分数化简要用的最大公因数。
ll n,sum=1,p;// sum记录分母,p记录分子。
int main()
{
read(n);
p=n;
for(int i=2;i<=n;i++)
{
ll fm=sum*i;
ll fz1=p*i,fz2=n*sum;// 分子分母通分才能相加。
ll fz=fz1+fz2;
ll k=gcd(fz,fm);
fz/=k;fm/=k;// 分数化简。
sum=fm;
p=fz;
}// 根据规律公式模拟分数相加。
if(p%sum==0) cout<<p/sum;// 整数判断,如果为整数输出整数。
else
{
ll num=0,k=p/sum,o=p,num1=0,u=sum;
while(k>0)
{
num++;
k/=10;
}// 求整数的位数。
while(u>0)
{
num1++;
u/=10;
}// 求分母的位数,最终要使分子、分母与分数线对其输出。
for(int i=1;i<=num;i++)
cout<<' ';
cout<<o%sum<<endl<<o/sum;// 空格的位数等于整数部分的位数。
for(int i=1;i<=num1;i++)
cout<<'-';// 减号的个数等于分母的位数。
cout<<endl;
for(int i=1;i<=num;i++)
cout<<' ';
cout<<sum<<endl;
}
return 0;
}// AC!!