剑指offer (43) n个骰子的点数

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

int g_maxValue = 6;

// ====================方法一====================
void Probability(int number, int* pProbabilities);
void Probability(int original, int current, int sum, int* pProbabilities);

void PrintProbability_Solution1(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;
}

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

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 PrintProbability_Solution2(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 * number + 1; ++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];
}

剑指offer (43) n个骰子的点数

时间: 2024-08-04 08:06:24

剑指offer (43) n个骰子的点数的相关文章

剑指offer——43数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数. 题解: 目前想不出更好的方法,待续更新... 1 class Solution { 2 private: 3 vector<int> min; 4 vector<int> max; 5 pub

剑指offer 43.左旋转字符串

43.左旋转字符串 题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”.是不是很简单?OK,搞定它! 思路一: 修正 n 的值后,让一个StingBuilder对象先后拼接 str 字符串中 n 之后的字符和 0 ~ n 之间的字符 1 public class Solution

剑指Offer对答如流系列 - n个骰子的点数

面试题60:n个骰子的点数 题目描述 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 问题分析 这个问题需要点高中数学的知识. 对于n个骰子,要计算出每种点数和的概率,我们知道投掷n个骰子的总情况一共有6^n种,因此只需要计算出某点数和的情况一共有几种,即可求出该点数之和的概率. 思路一:递归暴力 我们知道点数之和s的最小值为n,最大值为6*n,因此考虑用一个大小为(6*n-n+1)的数组存放不同点数之和的情况个数,那么,如果点数之和为x,那么把它

剑指 Offer 题目汇总索引

剑指 Offer 总目录:(共50道大题) 1. 赋值运算符函数(或应说复制拷贝函数问题) 2. 实现 Singleton 模式 (C#) 3.二维数组中的查找 4.替换空格               时间:O(n) 空间:O(1) 5.从尾到头打印链表 6. 重建二叉树          && 二叉树的各种遍历(BFS,DFS,DLR,LDR,LRD) 7.用两个栈实现队列 8.旋转数组的最小数字 9.斐波那契数列第 n 项        时间O(lgn) 10.一个整数的二进制表示中

剑指offer

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba来源:牛客网 剑指Offer中有这道题目的分析.这是一道二分查找的

剑指offer编程题Java实现——面试题12相关题大数的加法、减法、乘法问题的实现

用字符串或者数组表示大数是一种很简单有效的表示方式.在打印1到最大的n为数的问题上采用的是使用数组表示大数的方式.在相关题实现任意两个整数的加法.减法.乘法的实现中,采用字符串对大数进行表示,不过在具体的计算中,还是要将字符串转化成字符数组来进行计算. 实现两个大数的加法,要考虑到两个问题,两个数的和的位数问题,以及如何处理两个数按位相加产生的进位问题.首先两个整数相加,两个数的和的位数最多比最大的整数的位数多1:这样和的位数就确定了.对于进位问题,我的做法是先进行按位相加,相加操作完成后再按照

剑指offer编程题Java实现——面试题9斐波那契数列

题目:写一个函数,输入n,求斐波那契数列的第n项. 1 package Solution; 2 3 /** 4 * 剑指offer面试题9:斐波那契数列 5 * 题目:写一个函数,输入n,求斐波那契数列的第n项. 6 * 0, n=1 7 * 斐波那契数列定义如下:f(n)= 1, n=2 8 * f(n-1)+f(n-2), n>2 9 * @author GL 10 * 11 */ 12 public class No9Fibonacci { 13 14 public static void

剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈

剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()-1份元素poll出来,添加到另为一个为空的队列中,再把队列中最后的元素poll出来两个队列在栈不为空的情况下始终是有一个为空,另一个不为空的.push添加元素到非空的队列中,pop把非空队列的元素转移到另一个空的队列中,直到剩下最后一个元素,这个元素就是要出栈的元素(最后添加到队列中的元素). 1

剑指offer (2) c++实现singleton模式

转自:http://www.jellythink.com/archives/82 问题描述 现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能:在实际开发过程中,会专门有一个日志模块,负责写日志,由于在系统的任何地方,我们都有可能要调用日志模块中的函数,进行写日志.那么,如何构造一个日志模块的实例呢?难道,每次new一个日志模块实例,写完日志,再delete,不要告诉我你是这么干的.在C++中,可以构造一个日志模块的全局变量,那么在任何地方就都可以用了,是的,不错.但是