yooocen / dadaLearningBlogs

入职之后所有的学习文档
0 stars 0 forks source link

华为oj:成都麻将胡牌判决 #25

Open yooocen opened 6 years ago

yooocen commented 6 years ago

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

【思路】

【代码】

package learning;

public class majiang {
    private int[] Tmap = new int[10];
    private int[] Dmap = new int[10];
    private int[] Wmap = new int[20];

    private boolean T =false;
    private boolean D = false;
    private boolean W = false;

    /**
     * 是否同时有条、筒、万
     */
    public boolean isTDW(){
        return T && D && W;
    }
    /**
     * 是否是连对的胡牌
     */
    public boolean isLiandui(){
        boolean flag = true;
        for (int i: Tmap){
            if(i%2 !=0){
                flag=false;
            }
        }
        for (int i: Dmap){
            if(i%2 !=0){
                flag=false;
            }
        }
        for (int i: Wmap){
            if(i%2 !=0){
                flag=false;
            }
        }
        return flag;
    }
    /**
     * 用递推来判断是否能胡牌
     */
    public boolean isHu(int[] map){
        boolean onePair = false; //只能有一个对
        for (int i = 0 ; i <=9 ;i++){
            if(map[i]==0) continue;
            if(map[i]==2){
                map[2]-=2;
                if(onePair) return false; //如果前面有一个对,则肯定不能胡牌
                onePair = true;
            }else if(map[i] == 3){
                int cnt = 0;
                for (int j = i+1 ; j<=9;j++){
                    if (map[j]>0){
                        cnt++;
                    }else {
                        break;
                    }
                    if(cnt==2 || cnt==5 || cnt==8 || cnt==11){
                        onePair = true;
                        map[i]-=2;
                        map[i]-=1 ; map[i+1]-=1; map[i+2]-=1;
                    }else {
                        map[i]-=3;
                    }
                }
            } else if(map[i] ==4){
                return false;
            } else {
                if(i<=7 && map[i+1]>0 && map[i+2]>0){
                    map[i]-=1 ; map[i+1]-=1; map[i+2]-=1;
                }else {
                    return false;
                }
            }
        }
        return true;
    }
    public boolean IsmahjonggWIn(String cards){
        for (int i = 0 ; i<cards.length();i++){
            switch (cards.charAt(i+1)){
                case 'D' :{
                    int index = cards.charAt(i)-'0';
                    Dmap[index] ++ ;
                    D =true;
                    continue;
                }
                case 'T' :{
                    int index = cards.charAt(i)-'0';
                    Tmap[index] ++ ;
                    T =true;
                    continue;
                }
                case 'W' :{
                    int index = cards.charAt(i)-'0';
                    Wmap[index] ++ ;
                    W =true;
                    continue;
                }
            }
        }
        boolean canHu = false;
        if(!isTDW()){
            if (isLiandui()){
                canHu = true;
            }else {
                canHu = isHu(Dmap) && isHu(Tmap) && isHu(Wmap);
            }
        }else {
            canHu =false;
        }
        return canHu;
    }
}