如题,没有字牌,不考虑牌种
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 的情况下,优先消耗刻子










网友评论