hdu 校赛 玩骰子

http://acm.hdu.edu.cn/contests/contest_showproblem.php?cid=638&pid=1003

玩骰子

Problem Description
  Nias与Ains都特别喜欢玩骰子,而且都自以为比对方玩得更溜。
  终于有一天,他们决定用骰子来一决高下!
  一般的骰子玩法已经不足以体现他们的水平了,于是他们自创了一套玩法来PK:
首先,每人掷3个骰子;之后,可以选择其中一个骰子重新掷(当然也可以放弃这一步),最后,比较投掷结果的大小,结果大的那方获胜,一样的话为平局。
  大小比较规则为:
  三个一样数字的骰子称为三条;两个一样数字的骰子称为对子;只有一个数字的骰子成为散牌。三条>对子>散牌。当双方结果都为三条时,直接比较三条数字的大小;都有对子时,先比较对子数字的大小,若相同,再比较剩下的骰子的数字的大小;都只有散牌时,先比较最大的数字的大小,若相同,再比较次大的数字的大小,还相同,最后比较最小的数字的大小。

  现在Nias已经投了3个骰子,还剩一次机会可以选择其中一个骰子重新投(或不选),而且他已经知道了Ains的最后投掷结果,求Nias获胜的概率有多大。
 

Input
输入数据第一行为一个整数T,表示有T组测试数据。
接下来T行,每行6个1~6的整数,前三个表示Nias第一次的投掷结果,后三个表示Aias最终的投掷结果。
 

Output
请输出Nias获胜的概率,结果保留3位小数,每组输出占一行。
 

Sample Input
   
   
   
   
4 2 3 5 3 3 4 3 3 1 2 2 2 6 2 1 5 4 3 1 2 3 4 4 1
 

Sample Output
   
   
   
   
0.333 0.167 1.000 0.000
 
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <queue>
#include <stack>
#include <vector>
#include <map>

using namespace std;
typedef long long LL;

#define N 1100
#define INF 0x3f3f3f3f
#define PI acos (-1.0)
#define EPS 1e-8
#define met(a, b) memset (a, b, sizeof (a))

int A[5], B[5];

int judge (int C[])
{
    if (C[0]==C[1] && C[1]==C[2] && C[0]==C[1]) return 3;///条子
    if (C[0]==C[1] || C[1]==C[2]) return 2;///对子
    if (C[0]!=C[1] && C[1]!=C[2] && C[0]!=C[2]) return 1;///散牌
}

void fuzhi (int a[], int b[])
{
    for (int i=0; i<3; i++)
        a[i] = b[i];
}

bool compare (int a[], int b[])
{
    int A[10], B[10];
    fuzhi (A, a), fuzhi (B, b);

    sort (A, A+3), sort (B, B+3);

    int AT = judge (A), BT = judge (B);///三张牌的类型

    if (AT>BT) return true;///当A的类型大于B的时候,不需要再投掷即是A胜
    if (AT<BT) return false;

    if (AT==3 && BT==3) return A[0]>B[0];///A和B都是条子的情况

    if (AT==2 && BT==2)///A和B都是对子的情况
    {
        if (A[1] > B[1]) return true;
        if (A[1] < B[1]) return false;

        int AK, BK;
        if (A[0]!=A[1]) AK = A[0];
        else AK = A[2];

        if (B[0]!=B[1]) BK = B[0];
        else BK = B[2];

        return AK > BK;
    }

    if (AT==1 && BT==1)///A和B都是散牌的情况
    {
        if (A[2]>B[2]) return true;
        if (A[2]<B[2]) return false;
        if (A[1]>B[1]) return true;
        if (A[1]<B[1]) return false;
        return A[0]>B[0];
    }
}

int main ()
{
    int t;
    scanf ("%d", &t);

    while (t--)
    {
        scanf ("%d %d %d %d %d %d", &A[0], &A[1], &A[2], &B[0], &B[1], &B[2]);

        if (compare (A, B)) puts ("1.000");

        else
        {
            int c[4], maxn = 0;
            for (int i=0; i<3; i++)
            {
                fuzhi (c, A);///将A数组保存到C数组中,防止A发生变化,影响下一次判断
                int cnt = 0;

                for (int j=1; j<=6; j++)
                {
                    c[i] = j;///一一改变这三个筛子的值
                    if (compare (c, B))
                        cnt++;
                }
                maxn = max (maxn, cnt);///保存获胜的最大概率
            }
            printf ("%.3f\n", maxn*1.0/6);
        }
    }
    return 0;
}


你可能感兴趣的:(hdu 校赛 玩骰子)