【面试题043】n个骰子的点数
题目:
    把n个骰子扔在地上,所有骰子朝上一面的点数之和为s,
输入n,打印出s的所有可能的值出现的概率。
 
n个骰子的总点数,最小为n,最大为6n,根据排列组合的知识,那个骰子,所有点数的排列数为6^n。
我们先统计每一个点数出现的次数,然后把每一个点数出现的次数除以6^n,就能求出每个点数出现的概率。
 
思路一:
    基于递归求骰子点数,时间效率不够高。

  • 先把骰子分成两堆,第一堆只有一个,第二堆有n-1个,
  • 单独的那一个可能出现1到6的点数,我们需要计算从1-6的每一种点数和剩下的n-1个骰子来计算点数和。
  • 还是把n-1个那部分分成两堆,上一轮的单独骰子点数和这一轮的单独骰子点数相加,然后再和剩下的n-2个骰子来计算点数和。

不难发现这是一种递归的思路。

    定义一个长度为6n-n+1的数组,和为s的点数出现的次数保存到数组的第s-n个元素里。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 
#include <iostream>
#include <cstdio>

using namespace std;

int g_maxValue = 6;

void Probability(int original, int current, int sum, int *pProbabilities)
{
    if (current == 1)
    {
        pProbabilities[sum - original]++;
    }
    else
    {
        for (int i = 1; i <= g_maxValue; ++i)
        {
            Probability(original, current - 1, i + sum, pProbabilities);
        }
    }
}

void Probability(int number, int *pProbabilities)
{
    for (int i = 1; i <= g_maxValue; ++i)
    {
        Probability(number, number, i, pProbabilities);
    }
}

void PrintProbability(int number)
{
    if (number < 1)
    {
        return;
    }
    int maxSum = number * g_maxValue;
    int *pProbabilities = new int[maxSum - number + 1];
    for (int i = number; i <= maxSum; ++i)
    {
        pProbabilities[i - number] = 0;
    }

Probability(number, pProbabilities);

int total = pow( (double)g_maxValue, number);
    for (int i = number; i <= maxSum; ++i)
    {
        double ratio = (double)pProbabilities[i - number] / total;
        printf("%d: %e\n", i, ratio);
    }
    delete[] pProbabilities;
}

int main()
{
    PrintProbability(6);
    return 0;
}

 
思路二:
    基于循环求骰子点数,时间性能好。
  • 用两个数组来存储骰子点数的每一种出现的次数。
  • 在一次循环中,第一个数组中的第n个数字表示骰子和为n出现的次数。
  • 在下一次循环中我们加上一个新的骰子,此时和为n的骰子出现的次数应该等于上一次循环中骰子点数和为n-1、n-2、n-3、n-4、n-5与n-6的次数的综合,所以我们把另一个数组的第n个数字设为前一个数组对应的第n-1、n-2、n-3、n-4、n-5与n-6之和。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
#include <iostream>
#include <cstdio>

using namespace std;

int g_maxValue = 6;

void PrintProbability(int number)
{
    if (number < 1)
    {
        return ;
    }
    int *pProbabilities[2];
    pProbabilities[0] = new int[g_maxValue * number + 1];
    pProbabilities[1] = new int[g_maxValue * number + 1];
    for (int i = 0; i < g_maxValue; ++i)
    {
        pProbabilities[0][i] = 0;
        pProbabilities[1][i] = 0;
    }

int flag = 0;
    for (int i = 1; i <= g_maxValue; ++i)
    {
        pProbabilities[flag][i] = 1;
    }

for (int k = 2; k <= number; ++k)
    {
        for (int i = 0; i < k; ++i)
        {
            pProbabilities[1 - flag][i] = 0;
        }

for (int i = k; i <= g_maxValue * k; ++i)
        {
            pProbabilities[1 - flag][i] = 0;
            for (int j = 1; j <= i && j <= g_maxValue; ++j)
            {
                pProbabilities[1 - flag][i] += pProbabilities[flag][i - j];
            }
        }
        flag = 1 - flag;
    }
    double total = pow( (double)g_maxValue, number);
    for (int i = number; i <= g_maxValue * number; ++i)
    {
        double ratio = (double)pProbabilities[flag][i] / total;
        printf("%d: %e\n", i, ratio);
    }
    delete[] pProbabilities[0];
    delete[] pProbabilities[1];
}

int main()
{
    PrintProbability(6);
    return 0;
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

【面试题043】n个骰子的点数的更多相关文章

  1. 《剑指offer(第二版)》面试题60——n个骰子的点数

    一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...

  2. 《剑指offer》 面试题43 n个骰子的点数 (java)

    引言:写这篇文章的初衷只是想做个笔记,因为这道题代码量有点大,有点抽象,而书上并没有详细的注释.为了加深印象和便于下次复习,做个记录. 原题:把n个骰子扔到地上,所有骰子朝上一面的点数之后为s. 输入 ...

  3. 《剑指offer》面试题60. n个骰子的点数

    问题描述 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i ...

  4. 面试题 43 n 个骰子的点数

    ; void printfProbability(int number) { ) return; ]; p[] = ]; p[] = ]; memset(p[], , )); memset(p[], ...

  5. 【剑指offer】面试题43:n个骰子的点数

    第一种思路是,每一个骰子的点数从最小到最大,如果为1-6,那么全部的骰子从最小1開始,我们如果一种从左向右的排列,右边的最低,索引从最低開始,推断和的情况. def setTo1(dices, sta ...

  6. (剑指Offer)面试题43:n个骰子的点数

    题目: 把n个骰子仍在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 思路: s可能出现的值的范围为:n--6*n 1.全排列 回溯法枚举n个骰子(6面)的全排列,然 ...

  7. 剑指Offer面试题43(Java版):n个骰子的点数

    题目:把n个骰子仍在地上.全部骰子朝上一面的点数之和为s,输入n,打印出s的全部可能的值出现的概率. 解法一:基于递归求骰子的点数,时间效率不够高 如今我们考虑怎样统计每个点数出现的次数. 要向求出n ...

  8. 《剑指offer》第六十题(n个骰子的点数)

    // 面试题60:n个骰子的点数 // 题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s // 的所有可能的值出现的概率. #include <iostream> ...

  9. 新增6 n个骰子的点数

    /* * * 面试题43:n个骰子的点数 * 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s. * 输入n,打印出s的所有可能的值出现的概率. * */ #include <iostream ...

随机推荐

  1. WPF自定义控件(一)——Button

    接触WPF也有两个多月了,有了一定的理论基础和项目经验,现在打算写一个系列,做出来一个WPF的控件库.一方面可以加强自己的水平,另一方面可以给正在学习WPF的同行一个参考.本人水平有限,难免有一些错误 ...

  2. C#串口操作类,包括串口读写操作

    串口进行操作的类,其中包括写和读操作,类可设置串口参数.设置接收函数.打开串口资源.关闭串口资源,操作完成后,一定要关闭串口.接收串口数据事件.接收数据出错事件.获取当前全部串口.把字节型转换成十六进 ...

  3. Android--简单开发和使用ContentProvider数据共享

    今天学习的时候学到了ContentProvider数据共享这个东东,所以自己写了个小例子: 我们要开发ContentProvider的话,需要创建一个类去继承ContentProvider,里面会让你 ...

  4. Java检测文件是否UTF8编码

    介绍UTF-8编码规则 UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 字符最多只用到 3 字节长. Bigendian UCS-4 字节串的排列顺序是预定的. 字节 0 ...

  5. Linux: uid/euid/suid的关系

    三种进程用户的简单解释:三种用户/组ID:uid/gid: 实际用户/组IDeuid/egid: 有效用户/组ID, 进程执行某个应用的用户/组ID.suid/sgid: 设置用户/组ID, 应用所属 ...

  6. 通过Roslyn构建自己的C#脚本

    通过Roslyn构建自己的C#脚本 在下一代的C#中,一个重要的特性就是"Compiler as a Service",简单的讲,就是就是将编译器开放为一种可在代码中调用的服务.最 ...

  7. 如何让webapi只返回json格式数据

    最近脑子不好用,总记不住事,以前搞过让webapi只返回json格式的数据,今天有人问我又突然想不起了,后来总结一下,备忘一下,大概有下面几种处理方式 1.在WebApiConfig类的Registe ...

  8. 这个好像、也许、或许、大概、应该、Maybe真的可以算是传说中的Spring.Net了吧

                                                            这个好像.也许.或许.大概.应该.Maybe真的可以算是传说中的Spring.Net了吧 ...

  9. 15、android 用toast实现简单的进度显示

    if(mtoast!=null) { mtoast.setText(progress); } else { mtoast=Toast.makeText(getApplicationContext(), ...

  10. 前端之JavaScript第三天学习(7)-JavaScript-数据类型

    字符串.数字.布尔.数组.对象.Null.Undefined JavaScript 拥有动态类型 JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: 实例 var x      ...