頗有意思的題目。 就是給了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; }