T2 梭哈
时间限制:1000ms
【问题描述】
你在赌场里玩梭哈,已经被发了4张牌,现在你想要知道发下一张牌后你得到顺子的概率是多少?
假定赌场使用的是一副牌,四种花色的A、2、3、...、J、Q、K共52张,这副牌只发给你了4张,你的剩下一张牌从剩下48张中任意取出一张。
顺子指的是点数连续的五张牌,包括10、J、Q、K、A这种牌型。
注意:
a、顺子不包含同花顺,即构成顺子的五张牌花色不能相同;
b、另外,A、2、3、4、5和2、3、4、5、6都不是顺子。
【标准输入】
第一行为一个整数T,表示测试数据组数。
随后的每一行为四个被空格隔开的长度为2或3的字符串XY,表示你手里的牌。
其中,X为2~10、J、Q、K、A中一个,表示点数;Y为S、H、C、D分别表示黑桃、红心、梅花和方块。
【标准输出】
对于每组数据输出一行,用一个分数表示得到顺子的概率。
注意:你的分数需为最简分数,若答案为0则输出0/1。
【样例输入】
1
10S JS QS KD
【样例输出】
1/6
#include <stdio.h>
struct Pai
{
char a[5];//输入字符串的最大长度为3 但不能数组设为char a[3] 不然没有结束字符 字符串存储会发生错误
};
int main()
{
Pai b[4];//输入的为4个字符串
int c[4];// 存储牌的大小对应的数字
char d[4];//存储牌的花色
int t;
scanf("%d",&t);
while(t--)
{
int a=48;
int i,v=0;
for(i=0;i<4;i++)
{
scanf("%s",b[i].a);
}
for(i=0;i<4;i++)
{
if(b[i].a[0]=='2')//因为A,2,3,4,5 与2,3,4,5,6均不算顺子 所以出现了2 就可以知道此时不能组成顺子了
v=1;//v为标记
}
if(v==1)
{
printf("0/1\n");
continue;
}
for(i=0;i<4;i++)//将输入的长字符串进行拆分
{
if(b[i].a[0]=='1'&&b[i].a[1]=='0')
{
c[i]=10;//存储10
d[i]=b[i].a[2];
}
else
{
if(b[i].a[0]>='2'&&b[i].a[0]<='9')
{
c[i]=b[i].a[0]-'0';//存储2到9 数字
d[i]=b[i].a[1];
}
else
{
d[i]=b[i].a[1];
if(b[i].a[0]=='A')//因为只有10,J,Q,K,A才算顺子 所以可将A存为14
{ //方便下面进行计算 判断
c[i]=14;
}
else
{
if(b[i].a[0]=='J')
{
c[i]=11;
}
else if(b[i].a[0]=='Q')
{
c[i]=12;
}
else if(b[i].a[0]=='K')
{
c[i]=13;
}
}
}
}
}
int z;
for(int j=0;j<3;j++)
for(int h=j+1;h<4;h++)//将存储的4个数字进行从小到大排序 方便计算
{
if(c[j]>c[h])
{
z=c[j];
c[j]=c[h];
c[h]=z;
}
}
int k,sum=0;
for(k=0;k<3;k++)
{
sum=sum+c[k+1]-c[k];//求这挨着的4个数后一位减前一位的和
}
int p=0,q;
if(sum==3||sum==4)
{
if(sum==3)//和为3 代表是在两头进行加牌
{
if(c[0]==3||c[0]==11)
{
p=p+4;//若排完序后的第一张牌为3或11 则代表只能添加7或10 只有一种情况
q=1;//记录插入牌的数字大小的种类
}
else
{
p=p+8;//其他情况都可以有两种数目大小的牌插进来 使之组成顺子
q=2;
}
}
if(sum==4)//若和为4 则代表要选择的牌的数字大小在中间 例如 3 4 6 7 只有一种情况
{
p=p+4;
q=1;
}
}
else
{
printf("0/1\n");//其他情况 不管取到什么牌都不可能组成顺子
continue;
}
if(d[0]==d[1]&&d[1]==d[2]&&d[2]==d[3])//判断手里的四张牌是否为同一花色
{
p=p-q;//若不为同一花色 则要抽取的牌四种花色都可以 否则 要减去和手里的牌同一花色的牌
}
printf("%d/%d\n",1,a/p);//p可能为3 4 6 8 均能将48整除 所以可以直接输出
}
return 0;
}