剑指offer-n个骰子的点数

小易参加了一个骰子游戏,这个游戏需要同时投掷n个骰子,每个骰子都是一个印有数字1~6的均匀正方体。小易同时投掷出这n个骰子,如果这n个骰子向上面的数字之和大于等于x,小易就会获得游戏奖励。小易想让你帮他算算他获得奖励的概率有多大。

输入包括两个正整数n和x(1 ≤ n < 25, 1 ≤ x < 150),分别表示骰子的个数和可以获得奖励的最小数字和。
输出小易可以获得奖励的概率。如果概率为1,输出1,如果概率为0,输出0,其他以最简分数(x/y)的形式输出。
public class Main {
    public static void main(String[] arg) throws IOException {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int x = sc.nextInt();
        int maxVal = 6;
        long[][] count = new long[2][maxVal*n+1];//int 会越界
        int flag =0;
        for(int i=1;i<=maxVal;i++){//第一个骰子
            count[flag][i]=1;
        }
        for(int k=2;k<=n;k++){//第k个筛子
            for(int i=0;i<k;i++){//第k最小点为k
                count[1-flag][i] = 0;
            }
            for(int i=k;i<=maxVal*k;i++){
                count[1-flag][i] =0;
                for(int j=1;j<=i&&j<=maxVal;j++){
                    count[1-flag][i] += count[flag][i-j];
                }
            }
            flag =1-flag;
        }
        long total = (long)Math.pow(maxVal,n);
        long re = 0;
        for(int i=x;i<=maxVal*n;i++){
            re += count[flag][i];
        }
        long g =gcd(total,re);
        if(re==0){
            System.out.println(0);
        }
        else if(re ==total){
            System.out.println(1);
        }
        else{
            System.out.println(re/g+"/"+total/g);
        }
    }
    public static long gcd(long a,long b){
        return b==0?a:gcd(b,a%b);
    }
}

 

posted @ 2019-08-01 17:28  月半榨菜  阅读(207)  评论(0编辑  收藏  举报