超蛋疼模拟题,尤其是对我这个不会玩麻将的人来说,根本不知道该怎么判断胡牌,在网上搜到了一个判断胡牌的算法,这个只能判断那种最一般的情况,七小对和十三幺都没有。不过这两个也不怎么难,我把模版贴过来自己写了这两个函数,华丽丽的wa了,改了半天又和网上求这两种和法的函数比较才改好,真心伤不起,还是我代码能力太弱了……
#include <iostream> #include <cstring> #include <cstdio> #include <string> #include <map> #include <vector> #include <cmath> using namespace std; map<char,int> convert; vector<string> ans; int card[4][10]; char str[5]; int appear[100]; bool Win(int [4][10]); bool Analyze(int [],bool); bool Win (int allPai[4][10]) { int jiangPos;//“将”的位置 int yuShu;//余数 bool jiangExisted=false; //是否满足3,3,3,3,2模型 for(int i=0; i<4; i++) { //yuShu=(int)fmod(allPai[i][0],3); yuShu=allPai[i][0]%3; if (yuShu==1) { return false; } if (yuShu==2) { if (jiangExisted) { return false; } jiangPos=i; jiangExisted=true; } } for(int i=0; i<4; i++) { if (i!=jiangPos) { if (!Analyze(allPai[i],i==3)) { return false; } } } //该类牌中要包含将,因为要对将进行轮询,效率较低,放在最后 bool success=false;//指示除掉“将”后能否通过 for(int j=1; j<10; j++) //对列进行操作,用j表示 { if (allPai[jiangPos][j]>=2) { //除去这2张将牌 allPai[jiangPos][j]-=2; allPai[jiangPos][0]-=2; if(Analyze(allPai[jiangPos],jiangPos==3)) { success=true; } //还原这2张将牌 allPai[jiangPos][j]+=2; allPai[jiangPos][0]+=2; if (success) break; } } return success; } //分解成“刻”“顺”组合 bool Analyze(int aKindPai[],bool ziPai) { if (aKindPai[0]==0) { return true; } //寻找第一张牌 int j; for(j=1; j<10; j++) { if (aKindPai[j]!=0) { break; } } bool result; if (aKindPai[j]>=3)//作为刻牌 { //除去这3张刻牌 aKindPai[j]-=3; aKindPai[0]-=3; result=Analyze(aKindPai,ziPai); //还原这3张刻牌 aKindPai[j]+=3; aKindPai[0]+=3; return result; } //作为顺牌 if ((!ziPai)&&(j<8) &&(aKindPai[j+1]>0) &&(aKindPai[j+2]>0)) { //除去这3张顺牌 aKindPai[j]--; aKindPai[j+1]--; aKindPai[j+2]--; aKindPai[0]-=3; result=Analyze(aKindPai,ziPai); //还原这3张顺牌 aKindPai[j]++; aKindPai[j+1]++; aKindPai[j+2]++; aKindPai[0]+=3; return result; } return false; } bool isAllpair(int allPai[4][10]) { int c=0; for(int i=0;i<4;i++) { if(allPai[i][0]%2) return false; for(int j=1;j<10;j++) { if(allPai[i][j]==2) c++; } } return c==7; } bool otherjudge(int allPai[4][10]) { int c1=0,c2=0; for(int i=0;i<3;i++) { if(allPai[i][1]>=1) { c1++; if(allPai[i][1]==2) c2++; } if(allPai[i][9]>=1) { c1++; if(allPai[i][9]==2) c2++; } } for(int i=1;i<=7;i++) if(allPai[3][i]>=1) { c1++; if(allPai[3][i]==2) c2++; } return c1==13&&c2==1; } bool judge() { memset(card,0,sizeof(card)); int tot=0; for(int i=1; i<=37; i++) { if(i%10==0) { continue; } card[i/10][i%10]=appear[i]; card[i/10][0]+=appear[i]; } if(Win(card)) return true; else if(isAllpair(card)) return true; else if(otherjudge(card)) return true; else return false; } int main() { //freopen("input.txt","r",stdin); int t; scanf("%d",&t); convert['m']=0; convert['s']=10; convert['p']=20; convert['c']=30; while(t--) { ans.clear(); memset(appear,0,sizeof(appear)); for(int i=0; i<13; i++) { scanf("%s",str); appear[str[0]-'0'+convert[str[1]]]++; } for(int i=1; i<=37; i++) { if(i%10==0||appear[i]>=4) continue; appear[i]++; if(judge()) { string temp=""; temp+=(i%10)+'0'; if(i<10) temp+="m"; else if(i<20) temp+="s"; else if(i<30) temp+="p"; else temp+="c"; ans.push_back(temp); } appear[i]--; } if(ans.size()) { printf("%d",ans.size()); for(int i=0;i<ans.size();i++) cout<<" "<<ans[i]; cout<<endl; } else cout<<"Nooten"<<endl; } }