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 }
时间: 2024-08-01 06:28:35

hdu 4431 第37届ACM/ICPC 天津赛区现场赛A题 枚举的相关文章

hdu 4438 第37届ACM/ICPC 天津赛区现场赛H题

题意:Alice和Bob两个人去打猎,有两种(只)猎物老虎和狼: 杀死老虎得分x,狼得分y: 如果两个人都选择同样的猎物,则Alice得分的概率是p,则Bob得分的概率是(1-p): 但是Alice事先知道Bob先选老虎的概率是Q,问Alice得分的期望最大值是 求期望 如果先去打老虎,则会有bob先去打狼和bob去打老虎两种情况,期望相加则是alice去打老虎的期望,然后求打狼的期望,比较大小即可 1 #include<cstdio> 2 #include<iostream> 3

zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大.如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值.同样算出让集合B加入集合A的情况,取两者合并后

hdu 4435 第37届ACM/ICPC天津现场赛E题

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题目:给出N个城市,从1开始需要遍历所有点,选择一些点建立加油站,使得花费最少 这题的特殊性在于他的花费上,2^(i-1) 利用一个非常重要的性质,2^0+2^1+2^2……+2^i<2^(i+1) 所有编号<=i的所有点都建,总花费比建一个还少. 这里就贪心一下,先假设所有点都建,然后依次从编号大的删点,看看能不能遍历整个图 dist[i]表示

hdu 4432 第37届ACM/ICPC天津现场赛B题

题目大意就是找出n的约数,然后把约数在m进制下展开,各个数位的每一位平方求和,然后按m进制输出. 模拟即可 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9

hdu 4462 第37届ACM/ICPC 杭州赛区 J题

题意:有一块n*n的田,田上有一些点可以放置稻草人,再给出一些稻草人,每个稻草人有其覆盖的距离ri,距离为曼哈顿距离,求要覆盖到所有的格子最少需要放置几个稻草人 由于稻草人数量很少,所以状态压缩枚举,之后慢慢判断即可,注意放稻草人的格子是不需要覆盖的 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath>

hdu 4461 第37届ACM/ICPC杭州赛区I题

题意:给两个人一些棋子,每个棋子有其对应的power,若b没有或者c没有,或者二者都没有,那么他的total power就会减1,total power最少是1,求最后谁能赢 如果b或c出现的话,flag就标记为1,那么在判断的时候如果flag==0,就说明他们没出现过,那么就要-1,然后就wa了,必须要两个变量判断,不知道为什么 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #inclu

hdu 4463 第37届ACM/ICPC杭州赛区K题 最小生成树

题意:给坐标系上的一些点,其中有两个点已经连了一条边,求最小生成树的值 将已连接的两点权值置为0,这样一定能加入最小生成树里 最后的结果加上这两点的距离即为所求 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map>

zoj 3662 第37届ACM/ICPC长春赛区H题(DP)

题目:给出K个数,使得这K个数的和为N,LCM为M,问有多少种 f[i][j][k]表示选i个数,总和为j,最小公倍数为k memery卡的比较紧,注意不要开太大,按照题目数据开 这种类型的dp也是第一次做 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue&g

HDU 4435 charge-station (2012年天津赛区现场赛E题)

1.题目描述:点击打开链接 2.解题思路:本题利用DFS解决.不过本题的解法颇为巧妙,注意到2^0+2^1+...+2^(i-1)<2^i,这就意味着即使在0~i-1都建立加油站,费用也会小于单独在i处建立加油站.这就提示我们,可以一开始全部都建立加油站,然后从大到小依次尝试着删除加油站,如果可以删除,就删除,如果不可以,再添加上.那么该如何判断删除第i处之后是否可行呢?可以利用dfs判断,如果当前访问结点u是建立过加油站的,如果它的邻接点v也是建立了加油站的,且dist(u,v)<=d,那么