WY60. 骰子游戏
描述
小易参加了一个骰子游戏,这个游戏需要同时投掷n个骰子,每个骰子都是一个印有数字1~6的均匀正方体。输入描述
输入包括两个正整数n和x(1 ≤ n < 25, 1 ≤ x < 150),分别表示骰子的个数和可以获得奖励的最小数字和。输出描述
输出小易可以获得奖励的概率。 如果概率为1,输出1,如果概率为0,输出0,其他以最简分数(x/y)的形式输出。示例1
输入:
3 9
输出:
20/27
C 解法, 执行用时: 2ms, 内存消耗: 232KB, 提交时间: 2019-04-05
#include<stdio.h> #include<string.h> #define N_MAX 25 #define X_MAX 125 long long dp[N_MAX+1][X_MAX+1]; long long gcd(long long a, long long b){ while(b!=0){ long long tmp = a%b; a = b; b = tmp; } return a; } int main(int argc,char*argv[]){ int n, x; scanf("%d %d",&n,&x); if(x<=n){ printf("1"); return 0; } if(x>6*n){ printf("0"); return 0; } memset(dp,0,sizeof(dp)); for(int i = 1; i <= n; i++){ //i个骰子,数字和最小值i,最大值6*i for(int j = i; j <= 6*i; j++){ //当骰子数为1,或骰子数等于可以获得奖励的最小数字和,或最小数字和为极限最大值(6*i) //可能的骰子组合为1 if(i == 1 || i == j || j == 6*i) dp[i][j] = 1; else{ //i-1个骰子的情况 for(int k = 1; k <= 6; k++){ if(j-k>=i-1){ dp[i][j]+=dp[i-1][j-k]; } } } } } long long sum = 0; long long win_count = 0; for(int s = n; s <= 6 * n; s++){ sum += dp[n][s]; if(s >= x){ win_count +=dp[n][s]; } } long long g = gcd(sum,win_count); sum = sum/g; win_count = win_count/g; printf("%lld/%lld",win_count, sum); return 0; }
C 解法, 执行用时: 2ms, 内存消耗: 368KB, 提交时间: 2020-10-29
#include <stdio.h> #include <string.h> #define maxn 30 #define maxx 150 typedef long long ll; int n,x; //n-骰子数 x-可获得奖励的最小数字和 ll dp[maxn][maxx]; //i个筛子产生数字和j的可能情况数 ll Gcd(ll a,ll b){ if(b==0) return a; else return Gcd(b,a%b); } int main(){ int i,j,k; ll sum,p,gcd; scanf("%d %d",&n,&x); if(x==n) //最小数字和=骰子数, 则一定能获得奖励 printf("1\n"); else if(x>6*n) //最小数字和<所有骰子上面均为6时的数字之和, 则一定不能获得奖励 printf("0\n"); else{ memset(dp,0,sizeof(dp)); //初始化 for(i=1;i<=n;i++){ for(j=i;j<=6*i;j++){ if(i==1 || i==j || j==6*i) dp[i][j]=1; else{ for(k=1;k<=6;k++){ if(j-k>=i-1) dp[i][j]+=dp[i-1][j-k]; } } } } sum=p=0; for(i=n;i<=6*n;i++){ if(i>=x) p+=dp[n][i]; sum+=dp[n][i]; } gcd=Gcd(p,sum); printf("%lld/%lld\n",p/gcd,sum/gcd); } return 0; }