• 剑指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 }
  • 相关阅读:
    E. Directing Edges 解析(思維、拓樸排序)
    E. Modular Stability 解析(思維、數論、組合)
    E1. Weights Division (easy version) 解析(思維、優先佇列、樹狀DP)
    D. Prefixes and Suffixes 解析(思維、字串、Z-Algo)
    B. Jzzhu and Cities 解析(思維、最短路)
    D. Captain Flint and Treasure 解析(拓樸排序、Stack)
    B. Suffix Operations
    SPOJ-COT Count on a tree(树上的可持久化线段树)
    UPC GCPC2019 K: Move & Meet
    F. x-prime Substrings(AC自动机 + dp)
  • 原文地址:https://www.cnblogs.com/xiawen/p/3026468.html
Copyright © 2020-2023  润新知