(算法)成都麻将

题目:

说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
成都麻将只能包括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;
}

 

posted @ 2015-10-18 17:03  AndyJee  阅读(4165)  评论(0编辑  收藏  举报