剑指offer面试题43:n个筛子的点数
题目描述:
把n个筛子扔在地上,所有筛子朝上的一面点数之和为s,输入n,打印出s的所有可能的值出线的概率。
书上给了两种解法,第一种递归的方法由于代码太乱,没有看懂=。=
第二种方法很巧妙,lz已经根据书上的算法将其实现。
第二种算法思路如下:考虑两个数组来存储骰子点数的每一个总数出线的次数,在一次循环中,第一个数组中的第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 #include<iostream>
2 #include<math.h>
3 using namespace std;
4 void probability(int n)
5 {
6 int i,j,k,temp,max = 6*n,temp1[6*n+1],temp2[6*n+1];
7 for(j=0;j<6*n+1;j++)
8 {
9 temp1[j] = 0;
10 temp2[j] = 0;
11 }
12 for(j=1;j<7;j++)
13 {
14 temp1[j] = 1;
15 }
16 int flag = 0;
17 for(j = 2;j <= n;j++)//n dices to go
18 {
19 if(flag == 0)//对temp2进行操作
20 {
21 for(k = j;k < j * 6 + 1;k++)
22 {
23 temp = 1;
24 while((temp <= 6) && (k > temp))
25 {
26 //cout <<k <<" " << k-temp <<" " <<temp1[k-temp] << endl;
27 temp2[k] += temp1[k-temp];
28 temp++;
29 //cout << k <<endl;
30 }
31 }
32 flag = 1;
33 continue;//跳过剩下的循环
34 }
35 else if(flag == 1)//对temp1进行操作
36 {
37 for(k = j ;k < j * 6 + 1;k++)
38 {
39 temp = 1;
40 while((temp <= 6) && (k >temp) )
41 {
42 temp1[k] += temp2[k-temp];
43 temp++;
44 }
45 cout << "temp1[" << k <<"] " <<temp1[k] << endl;
46 }
47 flag = 0;
48 }
49 }
50 double total = pow((double)6,n);
51 if(flag == 0)
52 {
53 for(i = n;i< 6*n + 1 ;i++)
54 {
55 cout <<i<<"'s\t probability is:\t" <<((double)temp1[i])/total <<endl;
56 }
57 }
58 else
59 {
60 for(i = n;i< 6*n + 1 ;i++)
61 {
62 cout <<i<<"'s\t probability is:\t" <<((double)temp2[i])/total<<endl;
63 }
64 }
65 }
66
67 int main()
68 {
69 int n;
70 cin >> n;
71 int i;
72 probability(n);
73 system("pause");
74
75 return 0;
76 }
2 #include<math.h>
3 using namespace std;
4 void probability(int n)
5 {
6 int i,j,k,temp,max = 6*n,temp1[6*n+1],temp2[6*n+1];
7 for(j=0;j<6*n+1;j++)
8 {
9 temp1[j] = 0;
10 temp2[j] = 0;
11 }
12 for(j=1;j<7;j++)
13 {
14 temp1[j] = 1;
15 }
16 int flag = 0;
17 for(j = 2;j <= n;j++)//n dices to go
18 {
19 if(flag == 0)//对temp2进行操作
20 {
21 for(k = j;k < j * 6 + 1;k++)
22 {
23 temp = 1;
24 while((temp <= 6) && (k > temp))
25 {
26 //cout <<k <<" " << k-temp <<" " <<temp1[k-temp] << endl;
27 temp2[k] += temp1[k-temp];
28 temp++;
29 //cout << k <<endl;
30 }
31 }
32 flag = 1;
33 continue;//跳过剩下的循环
34 }
35 else if(flag == 1)//对temp1进行操作
36 {
37 for(k = j ;k < j * 6 + 1;k++)
38 {
39 temp = 1;
40 while((temp <= 6) && (k >temp) )
41 {
42 temp1[k] += temp2[k-temp];
43 temp++;
44 }
45 cout << "temp1[" << k <<"] " <<temp1[k] << endl;
46 }
47 flag = 0;
48 }
49 }
50 double total = pow((double)6,n);
51 if(flag == 0)
52 {
53 for(i = n;i< 6*n + 1 ;i++)
54 {
55 cout <<i<<"'s\t probability is:\t" <<((double)temp1[i])/total <<endl;
56 }
57 }
58 else
59 {
60 for(i = n;i< 6*n + 1 ;i++)
61 {
62 cout <<i<<"'s\t probability is:\t" <<((double)temp2[i])/total<<endl;
63 }
64 }
65 }
66
67 int main()
68 {
69 int n;
70 cin >> n;
71 int i;
72 probability(n);
73 system("pause");
74
75 return 0;
76 }