这个题是对麻将的一个模拟,要求求出所有可以“听"牌的可能,其实可以枚举所有的牌然后进行搜索看这张牌是否可以成为听牌,而如果拥有着张牌后能够成功的和牌,那么就说明这张牌能够成为听牌。
再添加某张牌后,选一个多余或等于2张的牌出来,然后进行进一步搜索判断这张牌是否可以成为听牌。
其中还需要注意的是同种牌不能超过4张。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const char* mahjong[]={"1T","2T","3T","4T","5T","6T","7T","8T","9T",
"1S","2S","3S","4S","5S","6S","7S","8S","9S",
"1W","2W","3W","4W","5W","6W","7W","8W","9W",
"DONG","NAN","XI","BEI",
"ZHONG","FA","BAI"};
int m[20],mm[50];
int GetIndex(char *str)
{
for(int i=0;i<34;i++)
if(!strcmp(mahjong[i],str))
return i;
}
bool DFSS(int res)
{
if(!res)
return true;
for(int i=0;i<34;i++)
if(mm[i]>=3)
{
mm[i]-=3;
if(DFSS(res-3))
return true;
mm[i]+=3;
}
for(int i=0;i<27;i++)
{
if(i%9<=6&&mm[i]&&mm[i+1]&&mm[i+2])
{
mm[i]--;mm[i+1]--;mm[i+2]--;
if(DFSS(res-3))
return true;
mm[i]++;mm[i+1]++;mm[i+2]++;
}
}
return false;
}
bool DFS()
{
for(int i=0;i<34;i++)
{
if(mm[i]>=2)
{
mm[i]-=2;
if(DFSS(12))
return true;
mm[i]+=2;
}
}
return false;
}
int main()
{
char str[100];
int mmas=1;
while(scanf("%s",str)!=EOF)
{
if(str[0]=='0')
break;
printf("Case %d:",mmas++);
m[0]=GetIndex(str);
for(int i=1;i<13;i++)
{
scanf("%s",str);
m[i]=GetIndex(str);
}
bool getans=false;
for(int i=0;i<34;i++)
{
memset(mm,0,sizeof(mm));
for(int j=0;j<13;j++)
mm[m[j]]++;
if(mm[i]>=4)
continue;
mm[i]++;
if(DFS())
{
getans=true;
printf(" %s",mahjong[i]);
}
mm[i]--;
}
if(!getans)
printf(" Not ready");
printf("\n");
}
return 0;
}