算法题:麻将判胡

2019-02-01  本文已影响4人  杰哥长得帅

如题,没有字牌,不考虑牌种
input: a[14] , 整数,1 <= ai <= 9,
output: boolean,true,false,是否胡牌

胡牌条件:2 + 4 * 3
1 * 2:雀头,(i,i)
4 * 3:面子
刻子:(i,i,i)
顺子:(i,i+1,i+2)
0 <= ci <= 4,ci 表示 i 的数量

a[14] = 11234234345666,T
a[14] = 12323445567892,F

1、搜索 + 回溯
枚举雀头,剩下的暴力搜索

    boolean canHu(int a[]) {
        int[] num = new int[10];
        for (int i = 0; i < a.length; i ++)
            num[a[i]] ++;
        for (int i = 0; i < 10; i ++) {
            if (a[i] >= 2) {
                num[a[i]] -= 2;
                if (canMatch(num)) return true;
                num[a[i]] += 2;
            }
        }
        return false;
    }
    
    boolean canMatch(int num[]) {
        boolean flag = false;
        for (int i = 1; i < 10; i ++) {
            if (num[i] > 0) {
                flag = true;
                break;
            }
        }
        if (!flag) return true;
        for (int i = 1; i < 10; i ++) {
            if (num[i] > 0) {
                if (num[i] >= 3) {
                    num[i] -= 3;
                    if (canMatch(num)) return true;
                    num[i] += 3;
                }
                if (i + 2 < 10 && num[i + 1] > 0 && num[i + 2] > 0) {
                    num[i] -= 1; num[i + 1] -= 1; num[i + 2] -= 1;
                    if (canMatch(num)) return true;
                    num[i] += 1; num[i + 1] += 1; num[i + 2] += 1;
                }
            }
        }
        return false;
    }

2、贪心
同样先枚举雀头,剩下的牌排序,然后从最小的开始考虑,如果该号码的牌数小于 3,则必须是顺子;否则可以贪心地认为是刻子,因为如果当成顺子,则要消耗掉后面连续的两对刻子(这和连续消耗三对刻子是一样的),这样的话可能会影响后面的顺子。所以同号码牌数不小于 3 的情况下,优先消耗刻子

上一篇 下一篇

猜你喜欢

热点阅读