2011 Alibaba Programming Contest_1009_Board Game Dice

Board Game Dice

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1411    Accepted Submission(s): 489


Problem Description
hh is a Board Game hobbyist, he often plays Board Game such as Catan, Carcassonne, The Werewolves, A song of ice and fire with friends.
To play the games, we need some dices, and these dices are very unusual. Maybe with eight or twelve sides.

hh plays with N friends today(including himself). They'll choose one person to be the judge. But the problem is: there is only a M-sided dice. How to pick a judge with the dice, so that everyone has equal probability of being chosen (the probability should always be 1/N)?
hh has an idea here:
1)Get x
Decide rolling the dice x times. x is the smallest integer to make M x larger than or equal to N.

2)Players choose sequences
Each player chooses a sequence with x elements (1~M).
For example, a 6-sides dice and x equal to 3, hh will gets sequence [5 4 6]. Players' sequences should be different from each other.(such as [6 4 5] is different from [5 4 6])

3)Pick the judge
Roll the dice for x times, we can get a result sequence, if someone has the same sequence as the result, he will be the judge; otherwise, repeat 1)-3), until the judge is chosen.

It's a bigger project, hh wants know the expected number of times we will need to throw dice to determine the judge.
 

Input
The first line is a number T(1<=T<=100), which represents the number of cases. The next T blocks following are the cases.
Each case contains two integer N , M(2<=N<=10 9, 2<=M<=20)
 

Output
For each case, output the number of case and expected number of rolling as an irreducible fraction in the following form: "a/b" (as shown in the sample output)
 

Sample Input
  
  
2 3 2 9 3
 

Sample Output
  
  
Case 1: 8/3 Case 2: 2/1
 

Author
NotOnlySuccess





这道题,我刚看到的时候有点混乱,不知道从何下手,看到很多人都过了,也只能试着想想了。然后我就根据样例yy了一下,yy的结果就是:(M^x) * x / N。yy的依据?木有。因为真的只是纯yy,我自己都不知道为什么要这样写,只是这样能得到样例的结果而已。第一次交了int,wa了;第二次交了long long,ac了。

此题正解:
每扔x次骰子,可能得到 M^x 种组合;被选了其中的 N 个组合,所以一次实验(即投x次)中,能选出一个judge的概率是 p = N / (M^x) 。
设 q = 1 - p,表示一次实验选不到一个judge的概率。
做k次实验,会出现一个judge的概率是: p * (q^(k-1)) (前k-1次实验失败,第k次实验成功)

题目要求的是平均要投多少次骰子,即是要计算平均要做多少次实验,然后再乘上x次。
而平均要做多少次实验,即实验次数的期望:累加(i * p * q^(i-1)),其中 i 从1到无穷大,表示实验的组数。
在这个累加的式子中,p是常数,可以提取出来,剩下的 累加(i * q^(i-1)) 可以通过极限计算得到 1 / ((1-q)^2),由于q = 1 - p,化简后整个式子变成:1 / p 。(对 x + x^2 + x^3 + ... = 1 / (1 - x) 这条式子两边求导即可知道为什么结果是 1 / ((1-q)^2) 了)
然后再乘上x:x / p = (M^x) * x / N

(知道正解后我表示很意外,居然让我一下子就yy到了,真是rp啊~不过用在这种地方真是浪费rp啊。。)

代码:

#include <iostream>

using namespace std;



typedef long long ll;



ll gcd(ll a, ll b)

{

    if (b == 0) return a;

    return gcd(b, a % b);

}



int main()

{

    int t;

    ll n, m;

    cin >> t;

    for (int k = 1; k <= t; k++)

    {

        cin >> n >> m;

        int x = 1;

        ll tmp = m;

        while (tmp < n)

        {

            tmp *= m;

            x++;

        }

        ll g = gcd(tmp*x, n);

        cout << "Case " << k << ": " << tmp*x/g << '/' << n/g << endl;

    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值