題目:
說起麻將,那可是川渝市民的最愛,無論親朋好友聚會,還是業務談判,總是少不了麻將的聲音。
成都麻將只能包括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; }
