为了使得在暴力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; }