每种牌只有34种,所以可以直接暴力枚举,然后先找出两张做将,然后接下来枚举三张做刻子或顺子就可以了。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/9/29.
// Mail:1016427040@qq.com or jasonshaosjj@gmail.com
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
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 c[34];
int convert(char *s)
{
for(int i=0;i<34;i++)
if(strcmp(mahjong[i],s)==0) return i;
return -1;
}
bool search(int dep)
{
for(int i=0;i<34;i++){
if(c[i]>=3){
if(dep==3) return true;
c[i]-=3;
if(search(dep+1)) return true;
c[i]+=3;
}
}
for(int i=0;i<=24;i++){
if(i%9<=6&&c[i]>=1&&c[i+1]>=1&&c[i+2]>=1){
if(dep==3) return true;
c[i]--;c[i+1]--;c[i+2]--;
if(search(dep+1)) return true;
c[i]++;c[i+1]++;c[i+2]++;
}
}
return false;
}
bool check()
{
for(int i=0;i<34;i++){
if(c[i]>=2){
c[i]-=2;
if(search(0)) return true;;
c[i]+=2;
}
}
return false;
}
int main()
{
int kase=0;
char s[10];
int maj[15];
while(scanf("%s",s))
{
if(s[0]=='0') break;
maj[0]=convert(s);
for(int i=1;i<13;i++){
scanf("%s",s);
maj[i]=convert(s);
}
printf("Case %d:",++kase);
bool ok=false;
for(int i=0;i<34;i++)
{
memset(c,0,sizeof(c));
for(int j=0;j<13;j++) c[maj[j]]++;
if(c[i]>=4) continue;
c[i]++;
if(check()){
ok=true;
printf(" %s",mahjong[i]);
}
c[i]--;
}
if(ok==false) printf(" Not ready");
printf("\n");
}
return 0;
}