本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
Atcoder 330 Texas Hold'em
Atcoder JAG Practice Contest for ACM-ICPC Asia Regional 2012
B - Texas hold 'em。
这是一道非常考验细节的题目,代码比较大,一般可以达到 500 500 500行/KaTeX parse error: Expected 'EOF', got '\mbox' at position 3: 20\̲m̲b̲o̲x̲{KB}。我是调了两天,差不多一共 10 10 10个小时这样子,最后发现题意理解不清……
(网上题解部分表述不严谨,请大家注意)
我们知道德州扑克是有 2 2 2张隐藏手牌、 5 5 5张公共牌,再从 7 7 7张牌中选取 5 5 5张进行押注、比较大小。
这道题首先给定你的 2 2 2张“隐藏手牌“,对手的 2 2 2张"隐藏手牌",以及 5 5 5张公共牌的其中 3 3 3张。
需要你求出在最后还不知道的 2 2 2张公共牌的所有可能组合中,你获胜的概率 p p p。
换言之,假设最后两张一共有 b b b种组合,而其中有 a a a种是你可以获胜的情况,那么输出 a b \frac{a}{b} ba(误差不超过 1 0 − 6 10^{-6} 10−6)。
注意:参与游戏的是标准扑克除去大小王共 52 52 52张牌,并且牌A
可以作为大于K
或小于2
中的一个。
首先我们根据计算可以得出,这道题直接暴力模拟是可以在 1 s 1s 1s之内出解的,因此我们直接采用暴力模拟。具体来讲,分成如下几步:
这道题中给出的输入是由花色+牌面值组成的字符串,因此我们需要把这个字符串转化为我们需要的数字。
注意:在本题中,我们将花色表示为 1 − 4 1-4 1−4,将牌面值表示为 2 − 14 2-14 2−14,便于后续存储。并且我们将A
视为 14 14 14。
设计一个函数将其分类即可。可以像我一样用一个结构体存储,然后设计一个构造函数完成上述功能。
接下来就是枚举所有可能的剩余公共牌。由于已经明确了有 7 7 7张牌,所以剩下的牌一共有 ( 52 − 7 ) × ( 52 − 8 ) 2 = 990 \frac{(52-7)\times (52-8)}{2}=990 2(52−7)×(52−8)=990种可能。但是这是无序二元组 ( a , b ) (a,b) (a,b)的情况。在实现代码时,由于不方便判重,因此干脆枚举有序二元组 ( a , b ) (a,b) (a,b)。这样在最终计算时并没有影响(表达式中分子和分母均乘以 2 2 2)。
检查部分是我和其它网上代码最大的不同。首先我们需要依次枚举每一种情况,判断是不是符合条件。
但是这里要注意的是对于每一个情况有 4 4 4种不同结果:
己方胜出。
对方胜出。
平局(双方都满足情况,且牌面相同)。
平局(双方均不满足情况)。
对于前 3 3 3种,我们可以直接返回状态(设其分别用1
、-1
、2
表示),对于第四种,我们就需要继续往下判断。
接下来,我们需要看一看每一种情况应该怎么处理。有标注注意细节的可能实现较为繁琐,请大家注意。
这个比较简单,我们只需要对于每一个花色依次判断 10 − 14 10-14 10−14是否存在即可。
注意:如果判断某一方拥有了皇家同花顺也不能直接返回,因为有可能五张牌全部来自公共牌。
我们需要把所有牌面为 14 14 14的转换为 1 1 1,且不需要保留 14 14 14的状态。
(一方面是因为有可能是 1 − 5 1-5 1−5的同花顺,因此要转换;另一方面是因为如果是 10 − 14 10-14 10−14的同花顺则在上一层就排除了,因此不用考虑 14 14 14的情况。)
然后对于每一个花色从 5 − 13 5-13 5−13依次枚举即可。
枚举每个牌面值判断四个花色是否都存在。
这个较为麻烦。我们首先遍历一遍,找出有 3 3 3张牌的,然后再找有 2 2 2张牌的,最后必须 3 3 3张和 2 2 2张都能找到才算找到,最后比较、返回。注意细节。
对于每个花色从大到小排序后比较。由于A
一定当成 14 14 14更优,因此不需考虑 1 1 1的情况。
首先把每个牌面值四种花色的数量加起来,然后判断是否有连续段长度 ≥ 5 \ge 5 ≥5。
注意,这里既要保留 14 14 14的状态也要加上 1 1 1的状态,但是由于顺子长度只有 5 5 5,因此不用担心产生重复。
同2.3.4
,只是不需要判断 2 2 2张,但是剩下四张要排好序,便于比较(如果前三张是牌面相同的)。注意细节。
类似2.3.4
查找两次出现次数为 2 2 2的牌,最后将剩下三张排好序便于比较。注意细节。
同2.3.8
。
直接将七张牌分别排序取最高 5 5 5张排序即可,操作最为简单。
我的代码 里对于每个判断我都重新记录了bool
数组,这点可以继续优化……然而足够通过本题。
#include
#include
#include
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]&<ot[i-1]&<ot[i-2]&<ot[i-3]&<ot[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&<ot[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&<ot[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;
}