小Hi在北方的暖气里温暖如春,小Ho却在南方的艳阳里感受大雪纷飞。距离使得他们连一起打麻将的机会都没有,失落的小Hi一个人玩起了麻将。
小Hi玩的是四川麻将,因此只有3种序数牌万、筒、条,每种花色一到九各4张。
小Hi起手拥有14张牌,之后小Hi每摸一张牌后,如果没有胡牌,就出一张牌,直至胡牌或牌被摸光。反正一个人玩又赢不到小Ho的钱,因此小Hi永远也不会选择暗杠。
胡牌的规则如下:
手中14张牌最多只能属于两个花色。
手中14张牌的牌型须满足下列两个条件之一:
1)3 + 3 + 3 + 3 + 2,其中的3代表一坎(指同花色且同数字、或同花色且数字相连的三张牌),其中的2代表一个对子(指两张同花色且同数字的牌)。
2)2 × 7,即14张牌构成7个对子,特别的,四张花色数字全相同的牌可以看作两个对子。 万、筒、条分别记为a, b, c,以下对能胡牌的牌型举出一些例子:
a1 a2 a3 a5 a5 a5 c3 c4 c5 c5 c6 c7 c7 c7
b2 b2 b5 b5 b7 b7 b8 b8 c1 c1 c2 c2 c3 c3
现给出小Hi的起手牌,并按顺序给出场上其余小Hi将要摸的牌。(小Hi只拿出了一副麻将的一部分牌玩,因此并不是每张牌都会被摸到。)
请计算小Hi最早在摸第几张牌之后就可能胡牌,天胡(起手牌构成胡牌牌型)记为第0张。无法胡牌输出-1。
每张牌用a, b或c其后紧接一个数字1-9表示。
第一行是一个正整数n (n <= 94),代表将要摸的牌。
第二行是14张手牌。
第三行是n张底牌,按摸牌顺序给出。
输出一个整数,代表最早在摸第几张牌之后可能胡牌,无法胡牌输出-1。
样例输入 12 a1 a1 a1 a2 a3 a4 a5 a6 a7 a8 a9 a9 a9 c1 c2 b1 b2 b4 b5 c1 b7 b8 a1 a2 a3 a4 样例输出 6..
不敢搜啊,其实算算搜索深度只有4层,还是可以无脑搜的
每一层节点得选取无非是 123连着的 或者三个重复的
到达第四层后 看看是否有对子即可
特判一下七小对
参考网上代码的实现:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int size = 255; int cnt[3][10]; int k1,k2; bool ok1_sub(int dep) { if (dep>4) { for(int i=1;i<=9;i++) if (cnt[k1][i]>=2) return true; for(int i=1;i<=9;i++) if (cnt[k2][i]>=2) return true; return false; } for(int i=1;i<=9;i++) { if (cnt[k1][i]>=3) { cnt[k1][i]-=3; if (ok1_sub(dep+1)) return true; cnt[k1][i]+=3; } } for(int i=1;i<=9;i++) { if (cnt[k2][i]>=3) { cnt[k2][i]-=3; if (ok1_sub(dep+1)) return true; cnt[k2][i]+=3; } } for(int i=1;i<=7;i++) { if (cnt[k1][i]&&cnt[k1][i+1]&&cnt[k1][i+2]) { cnt[k1][i]--,cnt[k1][i+1]--,cnt[k1][i+2]--; if (ok1_sub(dep+1)) return true; cnt[k1][i]++,cnt[k1][i+1]++,cnt[k1][i+2]++; } } for(int i=1;i<=7;i++) { if (cnt[k2][i]&&cnt[k2][i+1]&&cnt[k2][i+2]) { cnt[k2][i]--,cnt[k2][i+1]--,cnt[k2][i+2]--; if (ok1_sub(dep+1)) return true; cnt[k2][i]++,cnt[k2][i+1]++,cnt[k2][i+2]++; } } return false; } bool ok1() { for(k1=0;k1<=2;k1++) for( k2=k1;k2<=2;k2++) if (ok1_sub(1)) return true; return false; } bool ok2() { int num[3]; for(int i=0;i<=2;i++) { num[i]=0; for(int j=1;j<=9;j++)num[i]+=cnt[i][j]/2; } if (num[0]+num[1]>=7)return true; if (num[2]+num[1]>=7)return true; if (num[2]+num[0]>=7)return true; return false; } int main() { int n; cin>>n; char ss[4]; for(int i=1; i<=14; i++) { scanf("%s",ss); cnt[ ss[0]-'a' ][ss[1]-'0']++; } if (ok1()||ok2()) { return printf("0\n") ,0; } for(int i=1; i<=n; i++) { scanf("%s",ss); cnt[ ss[0]-'a' ][ss[1]-'0']++; if (ok1()||ok2()) return printf("%d\n",i) ,0; } return printf("-1\n"),0; return 0; }