hdu 4431 第37届ACM/ICPC 天津赛区现场赛A题 枚举

题意:就是给了13张牌。问增加哪些牌可以胡牌。m是数字,s是条,p是筒,c是数字
胡牌有以下几种情况:
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张。
 
模拟即可,第一个对子的情况需要枚举
 
很麻烦的模拟,但是貌似稳银的很需要这题,所以这种难度必须要弄懂,加油!!!
  1 #include<stdio.h>

  2 #include<iostream>

  3 #include<string.h>

  4 #include<algorithm>

  5 using namespace std;

  6 int cnt[35];

  7 bool judge4X3()

  8 {

  9     int ret=0;

 10     int tmp[35];

 11     for(int i=0;i<34;i++)tmp[i]=cnt[i];

 12 

 13     for(int i=0;i<=18;i+=9)

 14       for(int j=0;j<9;j++)

 15       {

 16           if(tmp[i+j]>=3)   //相同的

 17           {

 18               tmp[i+j]-=3;

 19               ret++;

 20           }

 21           while(j+2<9 && tmp[i+j] && tmp[i+j+1] &&tmp[i+j+2])   //不同的

 22           {

 23               tmp[i+j]--;

 24               tmp[i+j+1]--;

 25               tmp[i+j+2]--;

 26               ret++;

 27           }

 28       }

 29     for(int j=0;j<7;j++)    //东西南北

 30     {

 31         if(tmp[27+j]>=3)

 32         {

 33             tmp[27+j]-=3;

 34             ret++;

 35         }

 36     }

 37     if(ret==4)return true;

 38     return false;

 39 }

 40 bool judge1()   //判断对子和4个三连的情况

 41 {

 42     for(int i=0;i<34;i++)

 43     {

 44         if(cnt[i]>=2)

 45         {

 46             cnt[i]-=2;//枚举对子

 47             if(judge4X3())

 48             {

 49                 cnt[i]+=2;

 50                 return true;

 51             }

 52             cnt[i]+=2;

 53         }

 54     }

 55     return false;

 56 }

 57 bool judge2()   //判断全是对子的情况

 58 {

 59     for(int i=0;i<34;i++)   

 60     {

 61         if(cnt[i]!=2 && cnt[i]!=0)

 62           return false;

 63     }

 64     return true;

 65 }

 66 bool judge3()   //判断全部不相同的情况

 67 {

 68     for(int j=0;j<7;j++)

 69       if(cnt[j+27]==0)

 70         return false;

 71     for(int i=0;i<=18;i+=9)

 72     {

 73         if(cnt[i]==0 || cnt[i+8]==0)return false;

 74         for(int j=1;j<8;j++)    //不能再出现其他的牌

 75           if(cnt[i+j]!=0)

 76             return false;

 77     }

 78     return true;

 79 }

 80 bool judge()

 81 {

 82     if(judge1() || judge2() || judge3())return true;

 83     return false;

 84 }

 85 int main()

 86 {

 87     int T;

 88     char str[10];

 89     scanf("%d",&T);

 90     int ans[35],tol;

 91     while(T--)

 92     {

 93         memset(cnt,0,sizeof(cnt));

 94         for(int i=0;i<13;i++)

 95         {

 96             scanf("%s",&str);

 97             int t=str[0]-'1';

 98             if(str[1]=='m')t+=0;

 99             else if(str[1]=='s')t+=9;

100             else if(str[1]=='p')t+=18;

101             else t+=27;

102             cnt[t]++;

103         }   //将麻将排个序

104         tol=0;

105         for(int i=0;i<34;i++)

106         {

107             cnt[i]++;

108             if(cnt[i]<=4 && judge())    //麻将个数不能大于4,

109                ans[tol++]=i;            //符合条件

110             cnt[i]--;

111         }

112         if(tol==0)printf("Nooten\n");

113         else

114         {

115             printf("%d",tol);

116             for(int i=0;i<tol;i++)

117             {

118                 printf(" %d",(ans[i]%9)+1);

119                 if(ans[i]/9==0)printf("m");

120                 else if(ans[i]/9==1)printf("s");

121                 else if(ans[i]/9==2)printf("p");

122                 else printf("c");

123             }

124             printf("\n");

125         }

126     }

127     return 0;

128 }

 

你可能感兴趣的:(ICPC)