算牌王
描述
众所周知, X的牌技高超,因为X能够在1s内算出当前手中所有牌的总牌型数 (也就是出牌方法数),所以他被尊称为“算牌王”。而作为扑克菜鸡的你无法在1s内算出 来,于是你决定借助计算机的帮助。
注:为了简化问题,我们的手牌里不会出现大王、小王,并且不区分花色,所以总共有52张牌,每一种牌有4张。于是相同的牌型只会被计算一次,例如有3张3,对3只能算1次。
其中大小顺序为: 2>A>K>Q>J>0(10)>9>8>7>6>5>4>3
以下牌型将被计算:
- 单牌:一张牌。例: 3
- 对子:两张相同的牌。 例: 33
- 三条:三张相同的牌。 例: 333
- 炸弹:四张相同的牌。 例: 3333
- 葫芦:三条加对子 。 例: 33344
- 顺子:连续的五张牌(最大到A)。 例: 0JQKA
输入
输入的第一行包含正整数T,表示输入数据的组数。
接下来的T行每行包含字符串S代表当前的手牌。
数据保证:1<=T<=1000,1<=|s|<=20 ,字符串中只会出现数字字符 2—9,数字0字符(用来代表10),字符A(也就是1),J,Q,K。注意所有的字母都是大写字母。
输出
输出共T行。 对于每一行输入的手牌,输出牌型数(单独成行)。
输入样例 1
3
A23456700
AAA222
AAAA
输出样例 1
10
8
4
提示
样例说明:
第一个样例中有A到7各一张和两张10,存在如下的牌型:单牌8种(两个10只能算一次),1个顺子 34567,一个对10。所以总牌型为10个。
第二个样例中有2个单牌,2个对子(AA,22),两个三条 (AAA,222),两个葫芦(AAA22,222AA)。
第三个样例中有1个单牌,1个对子,1个三条,1个炸弹。
#include<stdio.h>
#include<string.h>
int ycx(int a[],int x) //顺子算法
{
int t=0;
for(int i=0;i<5;i++)
{
if(a[x]!=0)
{
x++;
t=1;
}
else
{
t=0;
break;
}
}
return t;
}
int jiecheng(int n) //阶乘算法
{
if(n==1)
return 1;
else if(n==0)
return 1;
else
return n*jiecheng(n-1);
}
int main()
{
int t,i,sum;
scanf("%d",&t);
char a[52];
int n;
int x,z;
int b1=0,b2=0;
int a1=0,a2=0,a3=0,a4=0,a5=0,a6=0; //依次代表6种情况的种数
int b[13],c[52];
getchar();
for(i=0;i<t;i++)
{
a1=0,a2=0,a3=0,a4=0,a5=0,a6=0; //初始化为0
gets(a);
n=strlen(a);
for(x=0;x<13;x++)
b[x]=0;
z=0;
for(x=0;x<n;x++)
{
if(a[x]>='3'&&a[x]<='9')
{
c[z]=a[x]-51;
z++;
}
else if(a[x]=='0')
{
c[z]=7;
z++;
}
else if(a[x]=='J')
{
c[z]=8;
z++;
}
else if(a[x]=='Q')
{
c[z]=9;
z++;
}
else if(a[x]=='K')
{
c[z]=10;
z++;
}
else if(a[x]=='A')
{
c[z]=11;
z++;
}
else if(a[x]=='2')
{
c[z]=12;
z++;
}
}
for(x=0;x<n;x++)
{
b[c[x]]++;
}
for(x=0;x<13;x++)
{
if(b[x]!=0)
a1++;
if(b[x]>=2)
a2++;
if(b[x]>=3)
a3++;
if(b[x]>=4)
a4++;
}
for(x=0;x<13;x++)
{
if(b[x]>=3)
{
b1++;
}
else if(b[x]==2)
b2++;
}
if(b1>0)
{
a5=a5+b2*b1;
if(b1>=2)
{
a5=a5+2*(jiecheng(b1)/(2*jiecheng(b1-2)));
}
}
else
a5=0;
b1=0;
b2=0;
for(x=0;x<9;x++)
{
if(b[x]!=0)
{
a6=a6+ycx(b,x);
}
}
sum=a1+a2+a3+a4+a5+a6;
printf("%d\n",sum);
}
return 0;
}
主要是葫芦算法有问题
利用组合数计算3个以上数量牌种的葫芦数
正确(泪奔)
谢谢!
好问题,点赞支持作者!