(算法)成都麻將


題目:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM