这个题是对麻将的一个模拟,要求求出所有可以“听"牌的可能,其实可以枚举所有的牌然后进行搜索看这张牌是否可以成为听牌,而如果拥有着张牌后能够成功的和牌,那么就说明这张牌能够成为听牌。
再添加某张牌后,选一个多余或等于2张的牌出来,然后进行进一步搜索判断这张牌是否可以成为听牌。
其中还需要注意的是同种牌不能超过4张。
代码:
#include<cstdio> #include<cstring> #include<iostream> 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 m[20],mm[50]; int GetIndex(char *str) { for(int i=0;i<34;i++) if(!strcmp(mahjong[i],str)) return i; } bool DFSS(int res) { if(!res) return true; for(int i=0;i<34;i++) if(mm[i]>=3) { mm[i]-=3; if(DFSS(res-3)) return true; mm[i]+=3; } for(int i=0;i<27;i++) { if(i%9<=6&&mm[i]&&mm[i+1]&&mm[i+2]) { mm[i]--;mm[i+1]--;mm[i+2]--; if(DFSS(res-3)) return true; mm[i]++;mm[i+1]++;mm[i+2]++; } } return false; } bool DFS() { for(int i=0;i<34;i++) { if(mm[i]>=2) { mm[i]-=2; if(DFSS(12)) return true; mm[i]+=2; } } return false; } int main() { char str[100]; int mmas=1; while(scanf("%s",str)!=EOF) { if(str[0]=='0') break; printf("Case %d:",mmas++); m[0]=GetIndex(str); for(int i=1;i<13;i++) { scanf("%s",str); m[i]=GetIndex(str); } bool getans=false; for(int i=0;i<34;i++) { memset(mm,0,sizeof(mm)); for(int j=0;j<13;j++) mm[m[j]]++; if(mm[i]>=4) continue; mm[i]++; if(DFS()) { getans=true; printf(" %s",mahjong[i]); } mm[i]--; } if(!getans) printf(" Not ready"); printf("\n"); } return 0; }