公式E(x)=n Σ 1/i
因为当已经拿到k张不同的时候 拿到不同牌的期望是 (n-k)/n ,1除于这个概率就是 n/(n-k) 然后从1到n加
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cstdio> #include<cassert> using namespace std; typedef long long ll; ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } struct Fraction { long long num; long long den; Fraction(long long num=0,long long den=1) { if(den<0) { num=-num; den=-den; } long long g=gcd(abs(num),den); this->num=num/g; this->den=den/g; } Fraction operator +(const Fraction &o)const { return Fraction(num*o.den+den*o.num,den*o.den); } Fraction operator -(const Fraction &o)const { return Fraction(num*o.den-den*o.num,den*o.den); } Fraction operator *(const Fraction &o)const { return Fraction(num*o.num,den*o.den); } Fraction operator /(const Fraction &o)const { return Fraction(num*o.den,den*o.num); } bool operator <(const Fraction &o)const { return num*o.den<den*o.num; } bool operator ==(const Fraction &o)const { return num*o.den==den*o.num; } }; int n; int main() { while(cin>>n) { Fraction ans(n,1); Fraction tmp(0,1); for(int i=1;i<=n;i++) tmp=tmp+Fraction(1,i); ans=ans*tmp; long long a,b,c; a=ans.num; b=ans.den; if(a/b!=0) { long long gd=gcd(a,b); a/=gd; b/=gd; c=a/b; a=a-c*b; } else c=0; if(a==0) printf("%lld\n",c); else { int l1,l2,l3; long long t1=c,t2=a,t3=b; l1=0; while(t1) { t1/=10; l1++; } l2=0; while(t2) { t2/=10; l2++; } l3=0; while(t3) { t3/=10; l3++; } if(l1!=0) { for(int i=0;i<=l1;i++) printf(" "); printf("%lld\n",a); printf("%lld ",c); int len=max(l2,l3); for(int i=0;i<len;i++) printf("-"); printf("\n"); for(int i=0;i<=l1;i++) printf(" "); printf("%lld\n",b); } else { printf("%I64d\n",a); int len=max(l2,l3); for(int i=0;i<len;i++) printf("-"); printf("\n"); printf("%I64d\n",b); } } } return 0; }
时间: 2024-11-05 15:58:07