题目大意:给出13张牌,问由这13张牌组成的牌型能否听牌
解题思路:枚举每一张牌,将其代入,看能否能胡,如果能胡的话,就表示这张是所听的牌。
判断能否能胡的话,用回溯的方法进行处理。先处理对子,因为必有一个对子的,然后再处理刻子和顺子
#include<cstdio>
#include<cstring>
const char *majiang[] = {"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","XI","NAN","BEI","ZHONG","FA","BAI"};
#define maxn 40
#define maxm 15
int temp[maxn];
char t[10];
int M[maxm];
int change() {
for(int i = 0; i < 34; i++)
if(strcmp(majiang[i],t) == 0)
return i;
return -1;
}
bool judge(int times) {
if(times == 4)
return true;
for(int i = 0; i < 34; i++)
if(temp[i] >= 3) {
temp[i] -= 3;
if( judge(times+1) )
return true;
temp[i] += 3;
}
for(int i = 0; i <= 24 ; i++)
if(i % 9 <= 6 && temp[i] && temp[i+1] && temp[i + 2]) {
temp[i]--;temp[i+1]--;temp[i+2]--;
if( judge(times + 1))
return true;
temp[i]++;temp[i+1]++;temp[i+2]++;
}
return false;
}
bool check() {
for(int i = 0; i < 34; i++) {
if(temp[i] >= 2) {
temp[i] -= 2;
if( judge(0) )
return true;
temp[i] += 2;
}
}
return false;
}
void DFS() {
bool flag = false;
for(int i = 0; i < 34; i++) {
memset(temp,0,sizeof(temp));
for(int j = 0; j < 13; j++)
temp[M[j]]++;
if(temp[i] >= 4)
continue;
temp[i]++;
if(check()) {
flag = true;
printf(" %s",majiang[i]);
}
temp[i]--;
}
if(!flag)
printf(" Not ready");
printf("\n");
}
int main() {
int mark = 1;
while(scanf("%s",t)) {
if(t[0] == '0')
break;
M[0] = change();
for(int i = 1; i < 13; i++) {
scanf("%s",t);
M[i] = change();
}
printf("Case %d:",mark++);
DFS();
}
return 0;
}