frankchenfu 的博客

frankchenfu 的博客

题解 AT330 【Texas hold 'em】

posted on 2018-07-21 14:05:03 | under 题解 |

Source

Atcoder JAG Practice Contest for ACM-ICPC Asia Regional 2012 B - Texas hold 'em

这是一道非常考验细节的题目,代码比较大,一般可以达到$500$行/$20\mbox{KB}$。我是调了两天,差不多一共$10$个小时这样子,最后发现题意理解不清……

1. 题意

(网上部分题解表述不严谨,请大家注意)

我们知道德州扑克是有$2$张隐藏手牌、$5$张公共牌,再从$7$张牌中选取$5$张进行押注、比较大小。

这道题首先给定你的$2$张“隐藏手牌“,对手的$2$张"隐藏手牌",以及$5$张公共牌的其中$3$张。

需要你求出在最后还不知道的$2$张公共牌的所有可能组合中,你获胜的概率$p$。

换言之,假设最后两张一共有$b$种组合,而其中有$a$种是你可以获胜的情况,那么输出$\frac{a}{b}$(误差不超过$10^{-6}$)。

注意:参与游戏的是标准扑克除去大小王共$52$张牌,并且牌A可以作为大于K或小于2中的一个。


2. 分析

首先我们根据计算可以得出,这道题直接暴力模拟是可以在$1s$之内出解的,因此我们直接采用暴力模拟。具体来讲,分成如下几步:

2.1 输入

这道题中给出的输入是由花色+牌面值组成的字符串,因此我们需要把这个字符串转化为我们需要的数字。

注意:在本题中,我们将花色表示为$1-4$,将牌面值表示为$2-14$,便于后续存储。并且我们将A视为$14$

设计一个函数将其分类即可。可以像我一样用一个结构体存储,然后设计一个构造函数完成上述功能。

2.2 枚举

接下来就是枚举所有可能的剩余公共牌。由于已经明确了有$7$张牌,所以剩下的牌一共有$\frac{(52-7)\times (52-8)}{2}=990$种可能。但是这是无序二元组$(a,b)$的情况。在实现代码时,由于不方便判重,因此干脆枚举有序二元组$(a,b)$。这样在最终计算时并没有影响(表达式中分子和分母均乘以$2$)。

2.3 检查

检查部分是我和其它网上代码最大的不同。首先我们需要依次枚举每一种情况,判断是不是符合条件。

但是这里要注意的是对于每一个情况有$4$种不同结果:

  • 己方胜出。

  • 对方胜出。

  • 平局(双方都满足情况,且牌面相同)。

  • 平局(双方均不满足情况)。

对于前$3$种,我们可以直接返回状态(设其分别用1-12表示),对于第四种,我们就需要继续往下判断。

接下来,我们需要看一看每一种情况应该怎么处理。有标注注意细节的可能实现较为繁琐,请大家注意。

2.3.1 Royal straight flush(皇家同花顺)

这个比较简单,我们只需要对于每一个花色依次判断$10-14$是否存在即可。

注意:如果判断某一方拥有了皇家同花顺也不能直接返回,因为有可能五张牌全部来自公共牌。

2.3.2 straight flush(同花顺)

我们需要把所有牌面为$14$的转换为$1$,且不需要保留$14$的状态。

(一方面是因为有可能是$1-5$的同花顺,因此要转换;另一方面是因为如果是$10-14$的同花顺则在上一层就排除了,因此不用考虑$14$的情况。)

然后对于每一个花色从$5-13$依次枚举即可。

2.3.3 Four of a kind(四张)

枚举每个牌面值判断四个花色是否都存在。

2.3.4 Full house(三带二)

这个较为麻烦。我们首先遍历一遍,找出有$3$张牌的,然后再找有$2$张牌的,最后必须$3$张和$2$张都能找到才算找到,最后比较、返回。注意细节

2.3.5 Flush(同花)

对于每个花色从大到小排序后比较。由于A一定当成$14$更优,因此不需考虑$1$的情况。

2.3.6 Straight(顺子)

首先把每个牌面值四种花色的数量加起来,然后判断是否有连续段长度$\ge 5$。

注意,这里既要保留$14$的状态也要加上$1$的状态,但是由于顺子长度只有$5$,因此不用担心产生重复。

2.3.7 Three of a kind(三张)

2.3.4,只是不需要判断$2$张,但是剩下四张要排好序,便于比较(如果前三张是牌面相同的)。注意细节

2.3.8 Two pairs(连对)

类似2.3.4查找两次出现次数为$2$的牌,最后将剩下三张排好序便于比较。注意细节

2.3.9 One pair(对子)

2.3.8

2.3.10 High card(高牌)

直接将七张牌分别排序取最高$5$张排序即可,操作最为简单。


3. 代码

我的代码 里对于每个判断我都重新记录了bool数组,这点可以继续优化……然而足够通过本题。

#include<cstdio>
#include<cstring>
#include<algorithm>

bool used[5][20];
struct card{
    int col,num;
    bool operator<(const card &rhs)const{
        return num>rhs.num;
    }
    card(){}
    card(char ch[]){
        switch(ch[0]){
            case 'S':{
                col=1;
                break;
            }
            case 'H':{
                col=2;
                break;
            }
            case 'D':{
                col=3;
                break;
            }
            case 'C':{
                col=4;
                break;
            }
        }
        switch(ch[1]){
            case 'T':{
                num=10;
                break;
            }
            case 'J':{
                num=11;
                break;
            }
            case 'Q':{
                num=12;
                break;
            }
            case 'K':{
                num=13;
                break;
            }
            case 'A':{
                num=14;
                break;
            }
            default:{
                num=ch[1]-'0';
                break;
            }
        }
        used[col][num]=1;
    }
}p1[10],p2[10],com[10];

int ___=0;
class checker{
    private:
        bool a[5][20],b[5][20];
        //Royal straight flush
        int check1(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            bool lans=0,rans=0;
            for(int i=1;i<=4;i++){
                if(a[i][10]&&a[i][11]&&a[i][12]&&a[i][13]&&a[i][14])
                    lans=1;
                if(b[i][10]&&b[i][11]&&b[i][12]&&b[i][13]&&b[i][14])
                    rans=1;
            }
            if(lans&&rans)
                return 2;
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //straight flush
        int check2(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num==14?1:p1[1].num]=1;
            a[p1[2].col][p1[2].num==14?1:p1[2].num]=1;
            b[p2[1].col][p2[1].num==14?1:p2[1].num]=1;
            b[p2[2].col][p2[2].num==14?1:p2[2].num]=1;
            a[com[1].col][com[1].num==14?1:com[1].num]=1;
            b[com[1].col][com[1].num==14?1:com[1].num]=1;
            a[com[2].col][com[2].num==14?1:com[2].num]=1;
            b[com[2].col][com[2].num==14?1:com[2].num]=1;
            a[com[3].col][com[3].num==14?1:com[3].num]=1;
            b[com[3].col][com[3].num==14?1:com[3].num]=1;
            a[col1][num1==14?1:num1]=1;b[col1][num1==14?1:num1]=1;
            a[col2][num2==14?1:num2]=1;b[col2][num2==14?1:num2]=1;
            int lans=0,rans=0;
            for(int i=1;i<=4;i++){
                for(int j=5;j<=13;j++){
                    if(a[i][j]&&a[i][j-1]&&a[i][j-2]&&a[i][j-3]&&a[i][j-4])
                        lans=std::max(lans,j);
                    if(b[i][j]&&b[i][j-1]&&b[i][j-2]&&b[i][j-3]&&b[i][j-4])
                        rans=std::max(rans,j);
                }
            }
            if(lans&&rans){ 
                if(lans==rans)
                    return 2;
                else
                    return lans>rans?1:-1;
            }
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //Four of a kind
        int check3(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int lans=0,rans=0;
            int lx[7]={0},rx[7]={0};
            for(int i=2;i<=14;i++){
                if(a[1][i]&&a[2][i]&&a[3][i]&&a[4][i])
                    lans=i;
                if(b[1][i]&&b[2][i]&&b[3][i]&&b[4][i])
                    rans=i;
                if(a[1][i]||a[2][i]||a[3][i]||a[4][i])
                    lx[++lx[0]]=i;
                if(b[1][i]||b[2][i]||b[3][i]||b[4][i])
                    rx[++rx[0]]=i;
            }
            for(int i=1;i<=lx[0];i++)
                if(lx[i]==lans)
                    lx[i]=0;
            std::sort(lx+1,lx+lx[0]+1);
            for(int i=1;i<=rx[0];i++)
                if(rx[i]==rans)
                    rx[i]=0;
            std::sort(rx+1,rx+rx[0]+1);
            if(lans&&rans){
                if(lans!=rans)
                    return lans>rans?1:-1;
                else{
                    if(lx[lx[0]]!=rx[rx[0]])
                        return lx[lx[0]]>rx[rx[0]]?1:-1;
                    return 2;
                }
            }
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //Full house(3+2)
        int check4(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int lans[2]={0,0},rans[2]={0,0};
            bool ltot=0,rtot=0;
            for(int i=14;i>=2;i--){
                if(a[1][i]+a[2][i]+a[3][i]+a[4][i]>=3){
                    lans[0]=i;
                    a[1][i]=a[2][i]=a[3][i]=a[4][i]=0;
                    break;
                }
            }
            for(int i=14;i>=2;i--){
                if(a[1][i]+a[2][i]+a[3][i]+a[4][i]>=2){
                    lans[1]=i;
                    break;
                }
            }
            if(lans[0]&&lans[1])
                ltot=1;
            for(int i=14;i>=2;i--){
                if(b[1][i]+b[2][i]+b[3][i]+b[4][i]>=3){
                    rans[0]=i;
                    b[1][i]=b[2][i]=b[3][i]=b[4][i]=0;
                    break;
                }
            }
            for(int i=14;i>=2;i--){
                if(b[1][i]+b[2][i]+b[3][i]+b[4][i]>=2){
                    rans[1]=i;
                    break;
                }
            }
            if(rans[0]&&rans[1])
                rtot=1;
            if(ltot&&rtot){
                if(lans[0]!=rans[0])
                    return lans[0]>rans[0]?1:-1;
                else
                    if(lans[1]!=rans[1])
                        return lans[1]>rans[1]?1:-1;
                    else
                        return 2;
            }
            if(ltot&&!rtot)
                return 1;
            if(!ltot&&rtot)
                return -1;
            return 0;
        }
        //Flush
        int check5(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int ltot[5][20],rtot[5][20];
            memset(ltot,0,sizeof(ltot));
            memset(rtot,0,sizeof(rtot));
            for(int i=1;i<=4;i++)
                for(int j=14;j>=2;j--){
                    if(a[i][j])
                        ltot[i][++ltot[i][0]]=j;
                    if(b[i][j])
                        rtot[i][++rtot[i][0]]=j;
                }
            int lans=0,rans=0;
            for(int i=1;i<=4;i++){
                if(ltot[i][0]>=5)
                    lans=i;
                if(rtot[i][0]>=5)
                    rans=i;
            }
            if(lans&&rans){
                for(int i=1;i<=5;i++)
                    if(ltot[lans][i]!=rtot[rans][i])
                        return ltot[lans][i]>rtot[rans][i]?1:-1;
                return 2;
            }
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //Straight
        int check6(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            a[p1[1].col][p1[1].num==14?1:p1[1].num]=1;
            a[p1[2].col][p1[2].num==14?1:p1[2].num]=1;
            b[p2[1].col][p2[1].num==14?1:p2[1].num]=1;
            b[p2[2].col][p2[2].num==14?1:p2[2].num]=1;
            a[com[1].col][com[1].num==14?1:com[1].num]=1;
            b[com[1].col][com[1].num==14?1:com[1].num]=1;
            a[com[2].col][com[2].num==14?1:com[2].num]=1;
            b[com[2].col][com[2].num==14?1:com[2].num]=1;
            a[com[3].col][com[3].num==14?1:com[3].num]=1;
            b[com[3].col][com[3].num==14?1:com[3].num]=1;
            a[col1][num1==14?1:num1]=1;b[col1][num1==14?1:num1]=1;
            a[col2][num2==14?1:num2]=1;b[col2][num2==14?1:num2]=1;
            int ltot[20],rtot[20];
            memset(ltot,0,sizeof(ltot));
            memset(rtot,0,sizeof(rtot));
            for(int i=1;i<=14;i++)
                for(int j=1;j<=4;j++){
                    ltot[i]+=a[j][i];
                    rtot[i]+=b[j][i];
                }
            int lans=0,rans=0;
            for(int i=5;i<=14;i++){
                if(ltot[i]&&ltot[i-1]&&ltot[i-2]&&ltot[i-3]&&ltot[i-4])
                    lans=i;
                if(rtot[i]&&rtot[i-1]&&rtot[i-2]&&rtot[i-3]&&rtot[i-4])
                    rans=i;
            }
            /*
            printf("***********\n");
            printf("%d %d %d %d %d %d %d\n",p1[1].num,p1[2].num,com[1].num,com[2].num,com[3].num,num1,num2);
            printf("%d %d %d %d %d %d %d\n",p2[1].num,p2[2].num,com[1].num,com[2].num,com[3].num,num1,num2);
            for(int i=1;i<=14;i++)
                printf("%d:l=%d  r=%d\n",i,ltot[i],rtot[i]);
            printf("\n****%d %d****\n",lans,rans);
            printf("***********\n"); 
            */
            if(lans&&rans){
                if(lans!=rans)
                    return lans>rans?1:-1;
                return 2;
            }
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //Three of a kind
        int check7(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int lans=0,rans=0;
            int lx[8]={0},rx[8]={0};
            for(int i=2;i<=14;i++){
                if(a[1][i]+a[2][i]+a[3][i]+a[4][i]==3)
                    lans=i;
                if(b[1][i]+b[2][i]+b[3][i]+b[4][i]==3)
                    rans=i;
                if(a[1][i]||a[2][i]||a[3][i]||a[4][i])
                    lx[++lx[0]]=i;
                if(b[1][i]||b[2][i]||b[3][i]||b[4][i])
                    rx[++rx[0]]=i;
            }
            for(int i=1;i<=lx[0];i++)
                if(lx[i]==lans)
                    lx[i]=0;
            std::sort(lx+1,lx+lx[0]+1);
            for(int i=1;i<=rx[0];i++)
                if(rx[i]==rans)
                    rx[i]=0;
            std::sort(rx+1,rx+rx[0]+1);
            if(lans&&rans){
                if(lans!=rans)
                    return lans>rans?1:-1;
                else{
                    if(lx[lx[0]]!=rx[rx[0]])
                        return lx[lx[0]]>rx[rx[0]]?1:-1;
                    if(lx[lx[0]-1]!=rx[rx[0]-1])
                        return lx[lx[0]-1]>rx[rx[0]-1]?1:-1;
                    return 2;
                }
            }
            if(lans&&!rans)
                return 1;
            if(!lans&&rans)
                return -1;
            return 0;
        }
        //Two pairs
        int check8(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int ltot[20],rtot[20];
            memset(ltot,0,sizeof(ltot));
            memset(rtot,0,sizeof(rtot));
            for(int i=2;i<=14;i++)
                for(int j=1;j<=4;j++){
                    ltot[i]+=a[j][i];
                    rtot[i]+=b[j][i];
                }
            int lans[5]={0,0,0,0,0},rans[5]={0,0,0,0,0};
            int lx[5]={0,0,0,0,0},rx[5]={0,0,0,0,0};
            for(int i=14;i>=2;i--)
                if(ltot[i]){
                    if(lans[0]<2&&ltot[i]>=2)
                        lans[++lans[0]]=i;
                    else
                        lx[++lx[0]]=i;
                }
            std::sort(lx+1,lx+lx[0]+1);
            for(int i=14;i>=2;i--)
                if(rtot[i]){
                    if(rans[0]<2&&rtot[i]>=2)
                        rans[++rans[0]]=i;
                    else
                        rx[++rx[0]]=i;
                }
            std::sort(rx+1,rx+rx[0]+1);
            if(lans[0]==2&&rans[0]==2){
                if(lans[1]!=rans[1])
                    return lans[1]>rans[1]?1:-1;
                if(lans[2]!=rans[2])
                    return lans[2]>rans[2]?1:-1;
                if(lx[lx[0]]!=rx[rx[0]])
                    return lx[lx[0]]>rx[rx[0]]?1:-1;
                return 2;
            }
            if(lans[0]==2&&rans[0]<2)
                return 1;
            if(lans[0]<2&&rans[0]==2)
                return -1;
            return 0;
        }
        //One pair
        int check9(int col1,int num1,int col2,int num2){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            a[p1[1].col][p1[1].num]=1;
            a[p1[2].col][p1[2].num]=1;
            b[p2[1].col][p2[1].num]=1;
            b[p2[2].col][p2[2].num]=1;
            a[com[1].col][com[1].num]=1;
            b[com[1].col][com[1].num]=1;
            a[com[2].col][com[2].num]=1;
            b[com[2].col][com[2].num]=1;
            a[com[3].col][com[3].num]=1;
            b[com[3].col][com[3].num]=1;
            a[col1][num1]=1;b[col1][num1]=1;
            a[col2][num2]=1;b[col2][num2]=1;
            int ltot[20],rtot[20];
            memset(ltot,0,sizeof(ltot));
            memset(rtot,0,sizeof(rtot));
            for(int i=2;i<=14;i++)
                for(int j=1;j<=4;j++){
                    ltot[i]+=a[j][i];
                    rtot[i]+=b[j][i];
                }
            int lans[5]={0,0,0,0,0},rans[5]={0,0,0,0,0};
            int lx[5]={0,0,0,0,0},rx[5]={0,0,0,0,0};
            for(int i=14;i>=2;i--)
                if(ltot[i]){
                    if(lans[0]<1&&ltot[i]>=2)
                        lans[++lans[0]]=i;
                    else
                        lx[++lx[0]]=i;
                }
            std::sort(lx+1,lx+lx[0]+1);
            for(int i=14;i>=2;i--)
                if(rtot[i]){
                    if(rans[0]<1&&rtot[i]>=2)
                        rans[++rans[0]]=i;
                    else
                        rx[++rx[0]]=i;
                }
            std::sort(rx+1,rx+rx[0]+1);
            if(lans[0]==1&&rans[0]==1){
                // printf("%d %d\n",lans[1],rans[1]);
                if(lans[1]!=rans[1])
                    return lans[1]>rans[1]?1:-1;
                if(lx[lx[0]]!=rx[rx[0]])
                    return lx[lx[0]]>rx[rx[0]]?1:-1;
                if(lx[lx[0]-1]!=rx[rx[0]-1])
                    return lx[lx[0]-1]>rx[rx[0]-1]?1:-1;
                if(lx[lx[0]-2]!=rx[rx[0]-2])
                    return lx[lx[0]-2]>rx[rx[0]-2]?1:-1;
                return 2;
            }
            if(lans[0]==1&&rans[0]<1)
                return 1;
            if(lans[0]<1&&rans[0]==1)
                return -1;
            return 0;
        }
        //High card
        int check10(int col1,int num1,int col2,int num2){
            int lans[10]={0,p1[1].num,p1[2].num,com[1].num,com[2].num,com[3].num,num1,num2};
            int rans[10]={0,p2[1].num,p2[2].num,com[1].num,com[2].num,com[3].num,num1,num2};
            std::sort(lans+1,lans+8);std::sort(rans+1,rans+8);
            for(int i=7;i>=3;i--)
                if(lans[i]!=rans[i]){
                    // printf("%d:%d %d\n",i,lans[i],rans[i]);
                    return lans[i]>rans[i]?1:-1;
                }
            return 2;
        }

    public:
        bool check(int col1,int num1,int col2,int num2){
            int opt;
            opt=check1(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check1\n");
            opt=check2(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check2\n");
            opt=check3(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check3\n");
            opt=check4(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check4\n");
            opt=check5(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check5\n");
            opt=check6(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            ___++;
            // printf("Finish check6\n");
            opt=check7(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check7\n");
            opt=check8(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check8\n");
            opt=check9(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check9\n");
            opt=check10(col1,num1,col2,num2);
            if(opt)
                return opt==2?0:opt>0;
            // printf("Finish check10\n");
            return 0;
        }
};
checker croupier;

int main(){
    char ch[10][3];
    while(scanf("%s",ch[0]),ch[0][0]!='#'){
        int lans=0,rans=0;
        memset(used,0,sizeof(used));
        for(int i=1;i<7;i++)
            scanf("%s",ch[i]);
        p1[1]=card(ch[0]);p1[2]=card(ch[1]);
        p2[1]=card(ch[2]);p2[2]=card(ch[3]);
        com[1]=card(ch[4]);com[2]=card(ch[5]);com[3]=card(ch[6]);
        for(int i=1;i<=4;i++)
            for(int j=2;j<=14;j++){
                if(used[i][j])
                    continue;
                for(int k=1;k<=4;k++)
                    for(int l=2;l<=14;l++){
                        if(used[k][l])
                            continue;
                        if(i==k&&j==l)
                            continue;
                        rans++;
                        if(croupier.check(i,j,k,l))
                            lans++;
                    }
            }
        printf("%.17Lf\n",(long double)lans/(long double)rans);
    }
    return 0;
}