数学期望模板题,不知道数学期望的点这里
得到第一个不同的名字需要1次,
得到第二个不同的名字需要N/(N-1)次 ,
因为只需与第一个名字不同即可, 概率是(N-1)/N,需要N/(N-1)次,
得到第三个不同名字需要N/(N-2)次,
······
得到第N个不同名字需要N/1次,
最后需要次数期望=1+N/(N-1)+N/(N-2)+···N/3+N/2+N/1 次。
直接求分数和就行,最后处理一下输出就行
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
int read() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0') {
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
void write(int x) {
if(x<0) {
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
void w(int x)
{
write(x);
putchar('\n');
}
int n;
int ans,a=0,b=1,u;
int num(int x)//求整数位数
{
int sum=0;
while(x)
{
sum++;
x/=10;
}
return sum;
}
signed main() {
n=read();
for(int i=n; i; i--) {//模拟分数通分相加过程,将其转换为带分数,a为分子,b为分母,ans为整数部分
b=b*i;
a=a*i+n*b/i;
u=__gcd(a,b);
a/=u;
b/=u;
ans+=a/b;
a%=b;
}
if(a==0)
{
write(ans);//分子为零,结果为整数
}
else
{
if(ans==0) //真分数,整数部分为零(这部分好像不用要,因为一个名字就需要1次,整数部分一定不为零)
{
int wi=num(b);
w(a);
for(int i=1;i<=wi;i++)
putchar('-');
putchar('\n');
write(b);
}
else
{
int wi1=num(ans),wi2=num(b);
for(int i=1;i<=wi1;i++)
putchar(' ');//将整数部分空出来,保证分子与分数线左端对齐
w(a);
write(ans);
for(int i=1;i<=wi2;i++)
putchar('-');
putchar('\n');
for(int i=1;i<=wi1;i++)//保证分母与分数线左端对齐
putchar(' ');
write(b);
}
}
return 0;
}