UVa10288 - Coupons

UVa10288 - Coupons

Coupons in cereal boxes are numbered 1 to n, and a set of one of each is required for a prize (a cereal box, of course). With one coupon per box, how many boxes on average are required to make a complete set of n coupons?
Input Input consists of a sequence of lines each containing a single positive integer n, 1 ≤ n ≤ 33, giving the size of the set of coupons. Input is terminated by end of file.
Output
For each input line, output the average number of boxes required to collect the complete set of n coupons. If the answer is an integer number, output the number. If the answer is not integer, then output the integer part of the answer followed by a space and then by the proper fraction in the format shown below. The fractional part should be irreducible. There should be no trailing spaces in any line of output.

這道題是問共n種不同的優惠券,每次取一個得到每種可能相同,問得到所有n種優惠券的次數的數學期望。
解:若已經得到k個優惠券,則P(得到剩下n-k個coupons) = (n-k)/n。因爲是幾何分佈,所以E(得到剩下n-k個coupons) = 1/P(得到剩下n-k個coupons = n / (n-k) 。
對於每取到一個coupons,設該事件爲xi,每個xi相對獨立。根據期望的線性性,E(∑xi) = ∑E(xi)。所以總的取到所有n個conpons的期望是∑n/i
剩下就是分數的模擬了,感覺寫的有點蠢。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> 
using namespace std;
typedef long long LL;

LL gcd(LL a, LL b){
    if (b == 0) return a;
    return gcd(b, a % b);
}

int places(LL num){
    int tmp = 0;
    while (num) {
        tmp++;
        num /= 10;
    }   
    return tmp;
}

struct Fraction{
    LL ne, de, in;
    void simplify(){
        in = ne / de;
        ne %= de;
    }
    Fraction operator + (const Fraction &b) const{
        Fraction res;
        LL bri1 = ne * b.de + b.ne * de;
        LL bri2 = de * b.de;
        LL tmp = gcd(bri1, bri2);
        res.ne = bri1 / tmp;
        res.de = bri2 / tmp;
        res.in = in + b.in + res.ne / res.de;
        res.ne = res.ne % res.de;
        return res;
    }
    void print(){
        int PL = places(in);
        for (int i = 1; i <= PL + 1; i++) printf(" ");
        printf("%lld\n", ne);
        printf("%lld ", in);
        for (int i = 1; i <= places(max(ne, de)); i++)
          printf("-");
        printf("\n");
        for (int i = 1; i <= PL + 1; i++) printf(" ");
        printf("%lld\n", de);
    }
};

int main()
{
    int n;
    while (~scanf("%d", &n)) {
      Fraction begin;
      begin.ne = begin.in = 0;
      begin.de = 1;
      for (int i = 1; i <= n; i++) {
        Fraction f;
        f.ne = n;
        f.de = i;
        f.in = 0;
        f.simplify();
        begin = begin + f;
      }
      if (begin.ne == 0){
        printf("%lld\n", begin.in);
        continue;
      }
      begin.print();
    }
    return 0;
}
發佈了32 篇原創文章 · 獲贊 1 · 訪問量 3990
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章