纯模拟胡麻将
十三幺,七对子(对子不能有重复),最普通的胡法
给出已有的13张牌,然后问有多少种胡法,输出所需牌
枚举所有的牌,对已有的14张牌,先判断十三幺和七对子
然后枚举用每一个对子当将,然后胡牌
对于c判断是否都为3或者0
对于m,s,p每种花色从左到右判断若>=3则-=3,若==1 || ==2 则与后两位形成顺子
#include "stdio.h"
#include "string.h"
struct node
{
int s[20],p[20],m[20],c[20];
}data,mark;
int ans;
char str[20][10];
int ssy()
{
int i;
for (i=1;i<=7;i++)
if (data.c[i]==0) return 0;
if (data.m[1]==0 || data.m[9]==0) return 0;
if (data.p[1]==0 || data.p[9]==0) return 0;
if (data.s[1]==0 || data.s[9]==0) return 0;
for (i=2;i<=8;i++)
if (data.m[i]!=0 || data.p[i]!=0 || data.s[i]!=0) return 0;
return 1;
}
int qdz()
{
int i;
for (i=1;i<=13;i++)
{
if (i<=7 && data.c[i]!=0 && data.c[i]!=2) return 0;
if (data.m[i]!=0 && data.m[i]!=2) return 0;
if (data.p[i]!=0 && data.p[i]!=2) return 0;
if (data.s[i]!=0 && data.s[i]!=2) return 0;
}
return 1;
}
int hu()
{
int i;
for (i=1;i<=7;i++)
if (mark.c[i]!=3 && mark.c[i]!=0) return 0;
for (i=1;i<=9;i++)
{
if (mark.m[i]>=3)
mark.m[i]-=3;
if (mark.m[i]!=0)
{
if (i>=8) return 0;
if (mark.m[i+1]<mark.m[i] || mark.m[i+2]<mark.m[i]) return 0;
else
{mark.m[i+1]-=mark.m[i];mark.m[i+2]-=mark.m[i];}
}
if (mark.p[i]>=3)
mark.p[i]-=3;
if (mark.p[i]!=0)
{
if (i>=8) return 0;
if (mark.p[i+1]<mark.p[i] || mark.p[i+2]<mark.p[i]) return 0;
else
{mark.p[i+1]-=mark.p[i];mark.p[i+2]-=mark.p[i];}
}
if (mark.s[i]>=3)
mark.s[i]-=3;
if (mark.s[i]!=0)
{
if (i>=8) return 0;
if (mark.s[i+1]<mark.s[i] || mark.s[i+2]<mark.s[i]) return 0;
else
{mark.s[i+1]-=mark.s[i];mark.s[i+2]-=mark.s[i];}
}
}
return 1;
}
int judge()
{
int i;
if (ssy()==1) return 1;
if (qdz()==1) return 1;
for (i=1;i<=9;i++)
{
mark=data;
if (mark.m[i]>=2)
{
mark.m[i]-=2;
if (hu()==1) return 1;
}
mark=data;
if (mark.p[i]>=2)
{
mark.p[i]-=2;
if (hu()==1) return 1;
}
mark=data;
if (mark.s[i]>=2)
{
mark.s[i]-=2;
if (hu()==1) return 1;
}
}
for (i=1;i<=7;i++)
{
mark=data;
if (mark.c[i]==2)
{
mark.c[i]-=2;
if (hu()==1) return 1;
}
}
return 0;
}
void dfs(char ch)
{
int i;
if (ch=='c')
for (i=1; i<=7; i++)
if (data.c[i]!=4)
{
data.c[i]++;
if (judge()==1)
{
ans++;
str[ans][0]=i+'0';
str[ans][1]='c';
str[ans][2]='\0';
}
data.c[i]--;
}
if (ch=='m')
for (i=1;i<=9;i++)
if (data.m[i]!=4)
{
data.m[i]++;
if (judge()==1)
{
ans++;
str[ans][0]=i+'0';
str[ans][1]='m';
str[ans][2]='\0';
}
data.m[i]--;
}
if (ch=='s')
for (i=1;i<=9;i++)
if (data.s[i]!=4)
{
data.s[i]++;
if (judge()==1)
{
ans++;
str[ans][0]=i+'0';
str[ans][1]='s';
str[ans][2]='\0';
}
data.s[i]--;
}
if (ch=='p')
for (i=1;i<=9;i++)
if (data.p[i]!=4)
{
data.p[i]++;
if (judge()==1)
{
ans++;
str[ans][0]=i+'0';
str[ans][1]='p';
str[ans][2]='\0';
}
data.p[i]--;
}
}
int main()
{
int Case,x,i;
char ch;
scanf("%d",&Case);
while (Case--)
{
memset(data.m,0,sizeof(data.m));
memset(data.p,0,sizeof(data.p));
memset(data.s,0,sizeof(data.s));
memset(data.c,0,sizeof(data.c));
for (i=1; i<=13; i++)
{
scanf("%d%c",&x,&ch);
if (ch=='s')
data.s[x]++;
if (ch=='p')
data.p[x]++;
if (ch=='m')
data.m[x]++;
if (ch=='c')
data.c[x]++;
}
ans=0;
dfs('m');
dfs('s');
dfs('p');
dfs('c');
if (ans==0)
printf("Nooten\n");
else
{
printf("%d",ans);
for (i=1; i<=ans; i++)
printf(" %s",str[i]);
printf("\n");
}
}
}