题目:
说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
成都麻将只能包括3种类型:条,筒,万。没有“门、东南西北、红中”。
每种牌都是数字从1到9,每个数字有4张,共36张。筒,万,条均一样。
胡牌简化规则如下:
1.必须有一个对子,即两张相同的牌,比如:两个2筒,两个4条等。
2.剩余的牌,每3张需要凑成一个有效牌,比如:3个一样的牌(3个2筒),或者3个顺子(1条2条3条),如果所有的牌都能够凑好,再满足规则2和1,有一个对子,并且所有的牌只有两种类型,那么就可以胡牌了。
3.假设牌不会出现碰的情况,即输入的牌肯定是13张。
4.输入牌肯定都是麻将牌,不用考虑异常输入;也不用考虑会输入“门”,“红中”等成都麻将中不会出现的牌。
5.条用T表示,D用D表示,万用W标识。
6.不用考虑输入的合法性,这个由函数的使用者保证。输入的牌为字符串,字母为大写的TDW”
要求根据13个已知输入,判断可以胡那几张牌。
输入:
输入13张麻将牌,如"1T8T6W6W5D4W1T3W6W2W5D6T1T"
输出:
输出胡牌个数和要胡的牌,
其中胡牌个数占一行输出,胡哪一张牌占一行输出,
胡多张牌,输出数促按照T/D/W的顺序从小到大排列(如1T5T6D7D3W8W)。
1
7T
思路:
遍历所有的牌,即在输入13张牌中,加入1T~9T,1D~9D,1W~9W中的任一张,然后判断该14张牌是否能胡。
代码:
#include<iostream> #include<sstream> #include<vector> using namespace std; #define NUM 9 void copy(vector<int> &tmp,const vector<int> &count); void GetCount(const string &str,vector<int> &count); bool TryHu(vector<int> &count,int len); bool IsHu(vector<int> &count); string translate(int i); int main(){ string str; while(cin>>str){ vector<int> count(NUM*3); vector<int> tmp(NUM*3); vector<string> HuPai; GetCount(str,count); for(int i=0;i<count.size();i++){ cout<<count[i]<<" "; } cout<<endl; for(int i=0;i<27;i++){ if(count[i]==4) continue; count[i]++; copy(tmp,count); bool flag=IsHu(tmp); if(flag){ //cout<< translate(i) <<endl; HuPai.push_back(translate(i)); } count[i]--; } cout<<HuPai.size()<<endl; for(int i=0;i<HuPai.size();i++) cout<<HuPai[i]<<endl; } return 0; } void GetCount(const string &str,vector<int> &count){ int n=str.size(); // n=13*2 int num; for(int i=0;i<n-1;i+=2){ if(str[i+1]=='T'){ num=str[i]-'0'; count[num-1]+=1; } if(str[i+1]=='D'){ num=str[i]-'0'; count[NUM+num-1]+=1; } if(str[i+1]=='W'){ num=str[i]-'0'; count[2*NUM+num-1]+=1; } } } void copy(vector<int> &tmp,const vector<int> &count){ int n=count.size(); for(int i=0;i<n;i++) tmp[i]=count[i]; } bool TryHu(vector<int> &count,int len){ if(len==0) return true; if(len%3==2){ for(int i=0;i<NUM*3;i++){ if(count[i]>=2){ count[i]-=2; if(TryHu(count,len-2)) return true; count[i]+=2; } } } else if(len%3==0){ for(int i=0;i<NUM*3;i++){ if(count[i]>=3){ count[i]-=3; if(TryHu(count,len-3)) return true; count[i]+=3; } } for(int i=0;i<NUM*3;i++){ if((i>=0 && i<NUM-2) || (i>=NUM && i<2*NUM-2) || (i>=2*NUM && i<3*NUM-2) ){ if(count[i]>0 && count[i+1]>0 && count[i+2]>0){ count[i]-=1; count[i+1]-=1; count[i+2]-=1; if(TryHu(count,len-3)) return true; count[i]+=1; count[i+1]+=1; count[i+2]+=1; } } } } return false; } bool IsHu(vector<int> &count){ bool result=TryHu(count,14); return result; } /* void int2str(const int &a,string &str){ stringstream ss; ss<<a; a>>str; } */ string translate(int i){ int n=i/NUM; string pre; stringstream ss; ss<<(i%NUM+1); ss>>pre; //int2str(i%9+1,pre); string r; switch(n){ case 0: r=pre+"T"; break; case 1: r=pre+"D"; break; case 2: r=pre+"W"; break; default: break; } return r; }