紫书例题 10-21 UVa 11971 连续概率

来源:互联网 发布:javascript注册页面 编辑:程序博客网 时间:2024/05/17 06:33

题意:有一根长度为n的木条,随机选k个位置把它们切成k+1段小木条。求这些小木条能组成一个多边形的概率。
分析:不难发现本题的答案与n无关。在一条直线上切似乎难以处理,可以把直线接成一个圆,多切一下,即在圆上随机选k+1个点,把圆周切成k+1段。根据对称性,两个问题的答案相同。新问题就要容易处理得多了:“组不成多边形”的概率就是其中一个小木条至少跨越了半个圆周的概率。设这个最长的小木条从点i开始逆时针跨越了至少半个圆周,则其他所有点都在这半个圆周之外。
除了点i之外其他每个点位于灰色部分的概率均为1/2,因此总概率为1/2 k 。点i的取法
有k+1种,因此“组不成多边形”的概率为(k+1)/2 k ,能组成多边形的概率为1-(k+1)/2 k 。

题目要求分数表示,套一个分数类模板,注意要用LL。

#include <bits/stdc++.h>using namespace std;const int maxn = 510;typedef long long LL;struct Fraction{    LL a, b; //a代表分子,b代表分母    Fraction(){        a = 0; b = 1;    }    void reduction(){        if(a == 0){            b = 1;            return;        }        LL gcdnum = __gcd(a, b);        a /= gcdnum;        b /= gcdnum;    }    Fraction(LL num){ //整数        a = num; b = 1;    }    Fraction(LL x, LL y){        a = x, b = y;        this->reduction();    }    void operator = (const LL &num){        a = num; b = 1;        this -> reduction();    }    void operator = (const Fraction &y){        a = y.a; b = y.b;        this -> reduction();    }    Fraction operator + (const Fraction &y) const{        LL gcdnum = __gcd(b, y.b);        Fraction tmp = Fraction(a * (y.b / gcdnum) + y.a * (b / gcdnum) , b / gcdnum * y.b);        tmp.reduction();        return tmp;    }    Fraction operator + (const LL &y) const{        return ((*this) + Fraction(y));    }    Fraction operator - (const Fraction &y) const{        return ((*this) + Fraction(-y.a, y.b));    }    Fraction operator - (const LL &y) const{        return ((*this) - Fraction(y));    }    Fraction operator * (const Fraction &y) const{        Fraction tmp = Fraction(a * y.a, b * y.b);        tmp.reduction();        return tmp;    }    Fraction operator / (const Fraction &y) const{        return ((*this) * Fraction(y.b, y.a));    }};int main(){    int T, ks = 0;    LL n , k;    scanf("%d", &T);    while(T--){        scanf("%lld%lld", &n, &k);        LL x = (1LL<<k) - k - 1;        LL y = (1LL<<k);        Fraction xx;        xx = Fraction(x, y);        printf("Case #%d: %lld/%lld\n", ++ks, xx.a, xx.b);    }    return 0;}
0 0
原创粉丝点击