题目
传送门
有n个数,问期望选取几个数能把这n个数全部取到。
题解
经典的期望题
如果从n个数中选一个数,显然概率就是 1/n,那么期望就是n (概率和期望互为倒数)
假设现在已经选出来了k个数,那么再从中选中一个数的概率为(n-k)/n ;期望就是n/(n-k)
所以 ans= n/n + n/(n-1) + n/(n-2) +….+ n/2 + n/1
把n提出来 ans=n*(1/1 + 1/2 +1/3+…+n-1/n +n/n);
继续整理,得到ans=n+1+n*(1/2 +1/3+…+n-1/n);
我在处理方式上,求 2+3+…+n-1 的lcm,然后用lcm除以每个因数就是同分之后的分母.具体看代码。
注意输出的要求,非常的恶心人。
注意开long long
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
ll n,m,fenmu=1,sum=1;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b) {return a*b/gcd(a,b);}
int main()
{
scanf("%lld",&n);
for (ll i=2; i<=n-1; i++)
fenmu=lcm(fenmu,i);
ll fenzi=0;
for (ll i=2; i<=n-1; i++)
{
fenzi+=(fenmu/i);
}
ll zheng=n+1;
fenzi*=n;
zheng+=(fenzi/fenmu);
fenzi%=fenmu;
ll g=gcd(fenzi,fenmu);
fenzi/=g; fenmu/=g;
if (fenzi==0) printf("%lld",zheng);
else
{
ll num=0,zhengnum=0;
ll k=fenmu;
while (k)
{
k/=10;
num++;
}
k=zheng;
while (k)
{
k/=10;
zhengnum++;
}
for (ll i=1; i<=zhengnum; i++) putchar(' ');
printf("%lld\n%lld",fenzi,zheng);
for (ll i=1; i<=num; i++) putchar('-');
printf("\n");
for (ll i=1; i<=zhengnum; i++) putchar(' ');
printf("%lld",fenmu);
}
return 0;
}
总结
注意读题,输出非常坑。
考试时要测大样例,比如 这道题有分数肯定是炸了,60分;
注意开long long int换long long时可以 Ctrl +R