題目大意:中國麻將,輸入13張牌,輸出你是否聽牌,若聽牌輸出你聽哪些牌。
題目思路:暴力,依次枚舉34張牌,即判斷當你手中多了這張牌後是否糊牌!判斷是否糊牌,首先剔除一對將,然後在每三張牌組合,牌的組合有多種,可以是順子,也可以是刻子,判斷時可以將刻子和順子分開判斷。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 40
char sname[34][6]={
"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"
};
char name[10];
int cnt[MAX],tot[MAX];
int set_read(char *s)
{
for (int i=0;i<34;i++)
{
if (strcmp(s,sname[i])==0)
return i;
}
}
int dfs(int x)
{
int i,j;
//分刻子與順子處理,因爲有些牌不存在順子
for (i=0;i<34;i++)
{
if (cnt[i]>=3)
{
if (x==3)
return 1;
cnt[i]-=3;
if (dfs(x+1)) //當不成立時回溯。
return 1;
cnt[i]+=3;
}
}
for (i=0;i<=24;i++)
{
if (i%9<7&&cnt[i]>0&&cnt[i+1]>0&&cnt[i+2]>0)
{
cnt[i]--;
cnt[i+1]--;
cnt[i+2]--;
if (x==3)
return 1;
if (dfs(x+1))
return 1;
cnt[i]++;
cnt[i+1]++;
cnt[i+2]++;
}
}
return 0;
}
int check()
{
int i;
for (i=0;i<34;i++)
{
if (cnt[i]>=2)
{
cnt[i]-=2;
if (dfs(0))
return 1;
cnt[i]+=2;
}
}
return 0;
}
int main()
{
int k=1;
while (scanf("%s",name)!=EOF)
{
if (strcmp(name,"0")==0)
break;
int i=0,j,x,ok=1;
x=set_read(name);
tot[i]=x;
for (i=1;i<13;i++)
{
scanf("%s",name);
x=set_read(name);
tot[i]=x;;
}
printf("Case %d:",k++);
//for (i=0;i<13;i++)
//printf("%d ",tot[i]);
//printf("\n");
for (i=0;i<34;i++)
{
memset(cnt,0,sizeof(cnt));
for (j=0;j<13;j++)
cnt[tot[j]]++;
if (cnt[i]>=4)
continue;
cnt[i]++;
if (check())
{
printf(" %s",sname[i]);
ok=0;
}
cnt[i]--;
}
if (ok)
{
printf(" Not ready");
}
printf("\n");
}
return 0;
}