【面试题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. 003-python基础-变量与常量

    一.变量的定义 变量就是用来在程序运行期间存储各种需要临时保存可以不断改变的数据的标示符,一个变量应该有一个名字,并且在内存中占据一定的存储单元,在该存储单元中存放变量的值. 二.变量的声明 #!/u ...

  2. Mysql数据库基本配置

    一 数据库基本配置包括编码方式 (安装环境是在linux下) 1.1 进入数据库 开启数据库服务:service mysqld start/restart(如果开启话可以重启) 关闭数据库服务:ser ...

  3. oracle11g rman验证备份有效性

    RMAN> restore validate controlfile; Starting restore at 21-NOV-13using target database control fi ...

  4. oracle expdp impdp

    一.不管导入还有导出都要先创建目录 1.创建目录 create directory my_dir as 'd:\yth';--生成目录(必须在指定位置先创建文件夹,名称最好与用户名一致) yth:是目 ...

  5. python: 命令选项及归类

    usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... Options and arguments (and corresp ...

  6. [CentOS 6.5 X64]讓firefox java plugin 啟動

    到ORACLE下載JRE http://www.oracle.com/technetwork/java/javase/downloads/index.html 我是X64所以下載 jre-7-linu ...

  7. 基于swift语言iOS8的蓝牙连接(初步)

    看过一些蓝牙App的事例,大体上对蓝牙的连接过程进行了了解.但是开始真正自己写一个小的BLE程序的时候就举步维艰了.那些模棱两可的概念在头脑中瞬间就蒸发了,所以还是决定从最基本的蓝牙连接过程进行.这里 ...

  8. linux下sort详解(sort对科学记数法的排序)

    1.参数解释 -t 设置分隔符 -k 设置比较域(列) -n 按数字比较 -g 科学记数法方式比较 -o 设置输出文件,与“>”相比可以设置输出到原文件,“>”会清空原文件 -r 降序(大 ...

  9. 16.如何设置Quartus II Programmer,保护pof不被读出

    Program时,把security bit勾上,点击start 这样examine时就不能正确的读出pof 读出来的pof 除文件头外,其余的内容全为0 怎么样,大家试试!

  10. Matlab实现均匀量化

    Matlab实现均匀量化 首先读入一个音频文件的前200个点,如果音频通道大于1则只取一个通道,滤掉其余的 得到音频文件的最大值和最小值,最大值和最小值的差除以2的4次方即16得到量化电平的端点间隔. ...