zoukankan      html  css  js  c++  java
  • (算法)成都麻将

    题目:

    说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
    成都麻将只能包括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;
    }
  • 相关阅读:
    关于CSDN指针讨论的心得
    VC++ 6.0 与VS2008 C++ DEBUG工具(Windows)介绍
    VC++ 申明静态变量的注意事项
    大家好,我是新的blue1000~
    [讨论]当我采用动态sql绑定datagrid分页的时候,遇到的问题
    我与Google有个对话
    [BK专访]一切以客户为中心,其它一切纷至沓来
    [译]在.net中使用GDI+来提高gif图片的保存画质
    微软能不能别这样坑爹啊,即使不中毒,也伤不起啊
    长见识!1021字节javascript写成的3D圣诞树
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4889809.html
Copyright © 2011-2022 走看看