Sample Input
1s1s1s2p3p4p6m7m8m1z1z1z2z 1s1s1s2p3p4p6m7m8m1z1z1z9m 1s1s1s2p3p4p6m7m8m1z1z1z1z 1s2s3s1s2s3s2s3s7s8s9s6z6z
Sample Output
1 2z 2 6m9m 0 3 1s4s6z
Hint
-
The hand in the first picture is not a
winning hand indeed, because there are fifteen tiles. If
1m or
9m is droped, it will be a
winning hand.Note that the input tiles is not ensured in the order of output.
题意
按一题目的要求输出摸到那些牌能胡牌
#include
#include
#include
using namespace std; struct node { int num; char kind; } s[100000]; char str[100]; int a[4][15]; int ta[4][15]; int len,cnt; int find(int num)//找出4个三个一组的 { int i,j; if(num == 0) return 1; for(i = 0; i<4; i++)//找出三个一样的 { for(j = 1; j<=9; j++) { if(a[i][j]<3) continue; a[i][j]-=3; if(find(num-1)) return 1; a[i][j]+=3; } } for(i = 0; i<3; i++)//找出一句话 { for(j = 1; j<=7; j++) { if(a[i][j] && a[i][j+1] && a[i][j+2]) { a[i][j]--,a[i][j+1]--,a[i][j+2]--; if(find(num-1)) return 1; a[i][j]++,a[i][j+1]++,a[i][j+2]++; } } } return 0; } int solve() { int i,j; for(i = 0; i<4; i++) { for(j = 1; j<=9; j++) { if(a[i][j]<2) continue; if(i==3 && j<=7) { a[i][j]-=2; if(find(4)) return 1; a[i][j]+=2; } else { a[i][j]-=2; if(find(4)) return 1; a[i][j]+=2; } } } return 0; } int main() { int i,j,k; while(~scanf("%s",str)) { cnt = 0; memset(a,0,sizeof(a)); for(i = 0; i<26; i+=2) { if(str[i+1] == 'm') a[0][str[i]-'0']++; else if(str[i+1] == 'p') a[1][str[i]-'0']++; else if(str[i+1] == 's') a[2][str[i]-'0']++; else if(str[i+1] == 'z') a[3][str[i]-'0']++; } char kind[5]="mpsz"; for(i = 1; i<=27+7; i++)//枚举所有摸到的牌 { int id = (i-1)/9; int no = i%9; if(no == 0) no = 9; memcpy(ta,a,sizeof(a)); if(id<4 && a[id][no]<4)//只有小于四张才能摸到 a[id][no]++; else continue; if(solve()) { s[cnt].num = no; s[cnt].kind = kind[id]; cnt++; } memcpy(a,ta,sizeof(ta)); } if(cnt == 0) { printf("0\n"); continue; } printf("%d ",cnt); for(i = 0; i