为了使得在暴力dfs判断选完将之后剩下的牌是否构成刻子和顺子;要用now【34】数组记录每张牌的个数,并且一直从有牌的内个最小编号牌判断其是否属于某个刻子或顺子;而且他所属顺子一定以他为最小值;
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 136 + 10;
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 ID(char* s){
for(int i=0;i<34;i++){
if(strcmp(mahjong[i],s)==0) return i;
}
}
char str[100];
int yuan[14],now[34];
bool dfs(int d,int num){
if(num==0) return true;
int nd = d;
for(int i=d;i<34;i++){
if(now[i]>=1){
nd = i;
break;
}
}
if(now[nd] >=3){
now[nd]-=3;
if(dfs(nd,num-3)) return true;
now[nd]+=3;
}
if(nd<27&&nd%9<=6&&now[nd]>=1&&now[nd+1]>=1&&now[nd+2]>=1){
now[nd]--; now[nd+1]--; now[nd+2]--;
if(dfs(nd,num-3)) return true;
now[nd]++; now[nd+1]++; now[nd+2]++;
}
return false;
}
bool check(){
for(int i=0;i<34;i++){
if(now[i]>=2){
now[i] -= 2;
if(dfs(0,12)) return true;
now[i] += 2;
}
}
return false;
}
int main()
{
int kase=1;
while(scanf("%s",str)==1){
if(str[0]=='0') break;
yuan[0] = ID(str);
for(int i=1;i<13;i++){
scanf("%s",str);
yuan[i]=ID(str);
}
printf("Case %d:",kase++);
int tot=0;
for(int i=0;i<34;i++){
memset(now,0,sizeof(now));
for(int j=0;j<13;j++) now[yuan[j]]++;
if(now[i]>=4) continue;
now[i]++;
if(check()){
tot++; printf(" %s",mahjong[i]);
}
}
if(!tot) printf(" Not ready\n");
else printf("\n");
}
return 0;
}