n个骰子的点数
最近复习面试题目,看到一道n个骰子的点数题目。正好新学了母函数法,用过来效果真不错,搜了一下貌似网上也还没有相关的,贴上来分享一下。
原题如下:把n个骰子仍在地上,所有骰子朝上一面的的和为s,输入n,打印出s的所有的值出现的概率。
构造母函数,G(x) = (x + x^2 + x^3 + x^4 + x^5 + x^6)^n 。 解释一下,x代表投一个骰子,一次可能的点数是1,2,3,4,5,6,且这些事件是等概率发生的,将G(x)展开得到的相应系数就是某个点数的出现次数。概率 = 当前点数出现次数 / 总得出现次数 ,下面是实现的代码:
1 #include <stdio.h> 2 3 void dice(int n){ 4 //可能点数 5 const int p[] = {1,2,3,4,5,6}; 6 int maxpoint = n*6; 7 8 //c1 c2 用于记录系数 9 int* c1 = new int[maxpoint + 1]; 10 int* c2 = new int[maxpoint + 1]; 11 for (size_t i = 0; i <= maxpoint; ++i) { 12 c1[i] = 0; 13 c2[i] = 0; 14 } 15 //构造一个 x + x^2 + x^3 + x^4 + x^5 + x^6 16 for (size_t i = 0; i<6; ++i) { 17 c1[p[i]] = 1; 18 } 19 20 //将G(x)模拟展开 21 for (size_t i = 2; i <= n; ++i) { 22 for ( size_t j = 0; j <= maxpoint; ++j) { 23 for (size_t k = 0; k < 6; ++k ) { 24 c2[ j + p[k] ] += c1[j]; 25 } 26 27 } 28 29 for ( size_t j = 0; j <= maxpoint; ++j) { 30 c1[j] = c2[j]; 31 c2[j] = 0; 32 } 33 34 } 35 36 int total = 0; 37 for (size_t i = 1; i <= maxpoint; ++i) { 38 total += c1[i]; 39 } 40 41 for (size_t i = 1; i <= maxpoint; ++i) { 42 if (c1[i]) { 43 printf("%lu:%lf\n", i, c1[i]*1.0 / total ); 44 } 45 } 46 47 48 delete [] c1; 49 delete []c2; 50 51 } 52 53 54 int main(){ 55 56 57 58 dice(6); 59 60 return 0; 61 62 }
浙公网安备 33010602011771号