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 }

 

posted @ 2015-04-17 23:12  miao_a_miao  阅读(194)  评论(0编辑  收藏  举报