632-掷骰子

632-掷骰子

内存限制:64MB 时间限制:3000ms Special Judge: No

accepted:9 submit:54

题目描述:
小明有m个骰子,小红有n个骰子。每一个骰子都是标准六面骰子。他们分别掷出自己的骰子,如果小明的点数和大,则小明胜;否则小红胜。求小明胜利的概率。
输入描述:
有T组数据。每组数据一行,m和n,用空格隔开。1 <= m, n <= 10
输出描述:
对于每一组数据,输出小明获胜的概率。每组输出占一行,用四舍五入法,精确到小数点后面6位。
样例输入:
复制
1
1 1 
样例输出:
0.416667


把一个骰子看作一个式子:x^1+x^2+x^3+x^4+x^5+x^6;

指数代表骰子的和,系数代表该组合出现的次数。


#include<map>
#include<stack>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define maxn 105
#define maxm 100005
#define mod 1000000007
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
ll a[maxn],b[maxn];
void sum(int x,ll *d){
    int num=6;
    ll c[maxn];
    mem(c,0);
    for(int i=1;i<=6;i++)d[i]=1;
    x-=1;
    while(x--){
        for(int i=1;i<=6;i++)c[i]=0;
        for(int i=1;i<=num;i++){
            for(int j=1;j<=6;j++){
                c[i+j]+=d[i];
            }
        }
        num+=6;
        for(int i=1;i<=num;i++){
            d[i]=c[i];
            c[i]=0;}
    }
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        mem(a,0);mem(b,0);
        int n,m;
        scanf("%d%d",&m,&n);
        ll ans=0;
        sum(m,a);sum(n,b);
        for(int i=1*n;i<=n*6;i++){
            for(int j=1;j<=m*6;j++){
                if(j>i)ans+=(a[j]*b[i]);
            }
        }
        int y=n+m;
        ll anss=pow(6,y);
        printf("%.6lf\n",(ans*1.0)/anss);
    }
}



posted @ 2018-05-07 20:58  _大美  阅读(203)  评论(0编辑  收藏  举报