颇有意思的题目。 就是给了13张牌。问增长哪些牌能够胡牌。 胡牌有如下几种状况: 1、一个对子 + 4组 3个相同的牌或者顺子。 只有m、s、p是能够构成顺子的。东西南北这样的牌没有顺子。 2、7个不一样的对子。 3、1m,9m,1p,9p,1s,9s,1c,2c,3c,4c,5c,6c,7c. 这13种牌每种都有,并且仅有这13种牌。确定是有一种2张。其余的1张。 首先是枚举18+7=34张牌,加进去构成14张牌,判断胡牌。 胡牌判断以下。 对于第一种状况:枚举每个对子。而后按照顺序找3张相同或者顺子。若是有三种相同的,构成3张相同的。没有就看能不能和后面的构成顺子。必定要按照顺序从小到大找过去。 1c```7c只能构成3张同样的。而后判断是否是恰好找到4组。 对于第二种状况:就是要每一种牌的数量要么是0,要么是2,这样必定是7个不一样的对子了。 对于第三种状况:就是要让这13种牌的数量不等于0,并且其余牌的数量为0;
代码:html
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; int cnt[35]; bool judge4X3() { int ret=0; int tmp[35]; for(int i=0;i<34;i++)tmp[i]=cnt[i]; for(int i=0;i<=18;i+=9) for(int j=0;j<9;j++) { if(tmp[i+j]>=3) { tmp[i+j]-=3; ret++; } while(j+2<9 && tmp[i+j] && tmp[i+j+1] &&tmp[i+j+2]) { tmp[i+j]--; tmp[i+j+1]--; tmp[i+j+2]--; ret++; } } for(int j=0;j<7;j++) { if(tmp[27+j]>=3) { tmp[27+j]-=3; ret++; } } if(ret==4)return true; return false; } bool judge1() { for(int i=0;i<34;i++) { if(cnt[i]>=2) { cnt[i]-=2;//枚举对子 if(judge4X3()) { cnt[i]+=2; return true; } cnt[i]+=2; } } return false; } bool judge2() { for(int i=0;i<34;i++) { if(cnt[i]!=2 && cnt[i]!=0) return false; } return true; } bool judge3() { for(int j=0;j<7;j++) if(cnt[j+27]==0) return false; for(int i=0;i<=18;i+=9) { if(cnt[i]==0 || cnt[i+8]==0)return false; for(int j=1;j<8;j++) if(cnt[i+j]!=0) return false; } return true; } bool judge() { if(judge1() || judge2() || judge3())return true; return false; } int main() { int T; char str[10]; scanf("%d",&T); int ans[35],tol; while(T--) { memset(cnt,0,sizeof(cnt)); for(int i=0;i<13;i++) { scanf("%s",&str); int t=str[0]-'1'; if(str[1]=='m')t+=0; else if(str[1]=='s')t+=9; else if(str[1]=='p')t+=18; else t+=27; cnt[t]++; } tol=0; for(int i=0;i<34;i++) { cnt[i]++; if(cnt[i]<=4 && judge()) ans[tol++]=i; cnt[i]--; } if(tol==0)printf("Nooten\n"); else { printf("%d",tol); for(int i=0;i<tol;i++) { printf(" %d",(ans[i]%9)+1); if(ans[i]/9==0)printf("m"); else if(ans[i]/9==1)printf("s"); else if(ans[i]/9==2)printf("p"); else printf("c"); } printf("\n"); } } return 0; }