UVa 10288 Coupous (條件概率)
阿新 • • 發佈:2018-09-29
urn nat assert char opera viso 分數類 divisor 次數 函數會\(WA\), 但是如果用\(C++\)函數庫裏的
題目
題目大意
大街上到處在賣彩票, 一元錢一張。購買撕開它上面的錫箔, 你會看到一個漂亮的圖案。圖案有\(n\)種, 如果你收集到所有\(n\)(\(n ≤ 33\))種彩票, 就可以得到大獎。請問, 在平均情況下, 需要買多少張彩票才能得到大獎呢? 如\(n = 5\)時的答案為\(11\frac{5}{12}\)。
題解
設已經有\(k\)個圖案: 平均拿\(\frac{n}{n - k}\)次就可多搜集一個, 所以總次數為:
\[n\sum_{i = 0}^{n - 1}\frac{1}{n - i}\]
然後再用個分數類就可以了。
此處再說一個奇妙的事情, 我如果用自己寫的GreatestCommonDivisor
__gcd
就能\(AC\), 至今不能理解。
還有輸出最好不要重載輸出流<<
運算符, 容易\(RE\)。
另外此題可打表。
代碼
#include <bits/stdc++.h> using namespace std; struct Fraction { long long numerator, denominator; Fraction(register long long knum = 0, register long long kden = 1) { if (kden < 0) { knum = -knum; kden = -kden; } assert(kden != 0); register long long g(__gcd((long long)abs(knum), kden)); this->numerator = knum / g; this->denominator = kden / g; } inline Fraction operator +(const Fraction& o) const { return Fraction(numerator * o.denominator + denominator * o.numerator, denominator * o.denominator); } inline Fraction operator -(const Fraction& o) const { return Fraction(numerator * o.denominator - denominator * o.numerator, denominator * o.denominator); } inline Fraction operator *(const Fraction& o) const { return Fraction(numerator * o.numerator, denominator * o.denominator); } inline Fraction operator /(const Fraction& o) const { return Fraction(numerator * o.denominator, denominator * o.numerator); } bool operator <(const Fraction& o) const { return numerator * o.denominator < denominator * o.numerator; } bool operator ==(const Fraction& o) const { return numerator * o.denominator == denominator * o.numerator; } }; int main(int argc, char const *argv[]) { register long long n, k, ans, cases(0); while (~scanf("%lld", &n)) { register Fraction ans; for (register int i(1); i <= n; ++i) { ans = ans + Fraction(n, i); } register long long t(ans.numerator / ans.denominator); ans.numerator -= t * ans.denominator; if (!ans.numerator) { printf("%lld\n", t); } else { register string s; register stringstream ss1, ss2; ss1 << t; ss1 >> s; register int space(s.size()); for (register int i(0); i <= space; ++i) putchar(' '); printf("%lld\n", ans.numerator); ss2 << ans.denominator; ss2 >> s; register int line(s.size()); printf("%lld ", t); for (register int i(0); i < line; ++i) putchar('-'); putchar('\n'); for (register int i(0); i <= space; ++i) putchar(' '); printf("%lld\n", ans.denominator); } } return 0; }
UVa 10288 Coupous (條件概率)