Throwing Dice LightOJ - 1064 || (勉强能用的)分数类
Posted 哈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Throwing Dice LightOJ - 1064 || (勉强能用的)分数类相关的知识,希望对你有一定的参考价值。
方法:
设ans[i][j]表示i个骰子点数恰好为j的概率。那么ans[1][1]到ans[1][6]都为1/6。
显然,$ans[i][j]=sum\{ans[i-1][j-k]\}(1<=k<=6,j>k)$
n和x上限很小,直接处理出所有点数恰好为某个值的结果,然后再做一遍类似前缀和的东西处理出所有点数大于等于某个值的结果。这里答案需要分数,于是乱写了一个分数结构体。
分数运算(没有优化的):
初始化空的分数:分子为0,分母为1
加法:先通分,然后加分子,然后约分
乘法:先互相约分,然后分子分母分别相乘
错误次数:1次
错误原因:由于把前缀和的范围限制与原数据的范围限制搞混,66行>=0写成>=i,导致WA
1 #include<cstdio> 2 typedef long long LL; 3 LL gcd(LL a,LL b) 4 { 5 LL t; 6 while(b!=0) 7 { 8 t=a; 9 a=b; 10 b=t%b; 11 } 12 return a; 13 } 14 struct X 15 { 16 LL a,b; 17 X() 18 { 19 a=0;b=1; 20 } 21 X(int x,int y) 22 { 23 a=x;b=y; 24 } 25 X operator+(const X& c) 26 { 27 X ans; 28 LL tmp=gcd(b,c.b); 29 ans.b=b/tmp*c.b; 30 ans.a=ans.b/b*a+ans.b/c.b*c.a; 31 tmp=gcd(ans.a,ans.b); 32 ans.a/=tmp; 33 ans.b/=tmp; 34 return ans; 35 } 36 X operator*(const X& c) 37 { 38 LL tmp1=gcd(a,c.b),tmp2=gcd(b,c.a); 39 X ans; 40 ans.a=a/tmp1*c.a/tmp2; 41 ans.b=b/tmp2*c.b/tmp1; 42 return ans; 43 } 44 void print() 45 { 46 if(b==1) 47 printf("%lld",a); 48 else 49 printf("%lld/%lld",a,b); 50 } 51 }ans[26][151],ans2[26][151]; 52 LL T,TT,n,x; 53 int main() 54 { 55 int i,j,k; 56 for(i=1;i<=6;i++) 57 ans[1][i]=(X){1,6}; 58 for(i=2;i<=25;i++) 59 for(j=i;j<=6*i;j++) 60 for(k=1;k<=6;k++) 61 if(j-k>0) 62 ans[i][j]=ans[i][j]+ans[i-1][j-k]*ans[1][1];//ans[1][1]就是1/6 63 for(i=1;i<=25;i++) 64 { 65 ans2[i][6*i]=ans[i][6*i]; 66 for(j=6*i-1;j>=0;j--) 67 ans2[i][j]=ans2[i][j+1]+ans[i][j]; 68 } 69 scanf("%lld",&T); 70 for(TT=1;TT<=T;TT++) 71 { 72 scanf("%lld%lld",&n,&x); 73 printf("Case %lld: ",TT); 74 ans2[n][x].print(); 75 puts(""); 76 } 77 return 0; 78 }
以上是关于Throwing Dice LightOJ - 1064 || (勉强能用的)分数类的主要内容,如果未能解决你的问题,请参考以下文章