https://nanti.jisuanke.com/t/39612
题面:
在麻将游戏中,有 3434 种牌,分别是 1-91−9 的万,1-91−9 的筒,1-91−9 的条,以及 77 种字牌 “东”,“南”,“西”,“北”,“白”,“发”,“中”。 这 3434 种牌各四张,共 136136 张。 如果你手牌中凑够了 1414 张牌,满足一定的牌型条件,就称作“和牌”。 这个牌型有很多种,但在本题中,只考虑最基本的一种,44 个面子 + 11 个雀头组成的牌型。 面子是刻子和顺子的统称,雀头是对子。 刻子指的是,三张一样的牌。 顺子指的是,三张连续的牌,注意,只有非字牌(也就是万,筒,条)才能连续,例如一二三万,四五六筒,并且不能循环连续,比如九一二条就不算顺子。 对子指的是,两张一样的牌。 现在,zcy 手中有 1313 张牌,并且再得到某一张牌,就可以和牌,而你的目标就是输出能使 zcy 和牌的牌。 注意一种特殊情况,如果你手牌中某张牌有四张,而再得到这张牌也能和牌,这张牌在本题中不需要输出,因为这张牌总共就只有四张,不可能拿到手了。 (如果你知道什么是杠,请假装不能杠,如果你不知道,那就不需要知道了。)
输入要求:
1−9 万用对应数字 + 一个小写 mm 表示 1-91−9 条用对应数字 + 一个小写 ss 表示 1-91−9 筒用对应数字 + 一个小写 pp 表示 东南西北白发中分别用 1-71−7 的数字 + 一个小写 zz 表示 输入多组数据,每组共 1313 个数字 + 字母的组合,用空格隔开 输入保证有解
输入格式:
对于每组数据,输出若干行,每行一个听牌,按照万,条,筒,字的顺序输出听牌,同类型按照数从小到大输出 数据组数不超过 1010 组
输入案例:
1s 2s 3s 4s 5s 6s 7s 8s 9s 1z 1z 3p 4p
输出案例:
2p
5p
思路:
胡牌是这样的: 一个对子 + 4组 3个相同的牌或者顺子。 只有m、s、p是可以构成顺子的。东西南北这样的牌没有顺子。 思路: 枚举每一个对子。然后按照顺序找3张相同或者顺子。如果有三种相同的,构成3张相同的。没有就看能不能和后面的构成顺子。一定要按照顺序从小到大找过去。 1c```7c只能构成3张一样的。然后判断是不是刚好找到4组。
代码:
1 #include <stdlib.h> 2 #include<iostream> 3 #include<bits/stdc++.h> 4 #include<cmath> 5 #define ll long long 6 const int INF=0x3f3f3f3f; 7 #define mod 1000000007 8 using namespace std; 9 //priority_queue 10 int cnt[35]; 11 int ant[35]; 12 int ju() 13 { int cnt1[35]; 14 for(int i=0;i<34;i++) 15 cnt1[i]=cnt[i]; 16 int sum=0; 17 for(int i=0;i<=18;i+=9) 18 for(int j=0;j<9;j++) 19 { 20 if(cnt1[i+j]>=3) 21 { 22 cnt1[i+j]-=3; 23 sum++; 24 } 25 while(j+2<9&&cnt1[i+j]&&cnt1[i+j+1]&&cnt1[i+j+2]) 26 { 27 cnt1[i+j]--; 28 cnt1[i+1+j]--; 29 cnt1[i+j+2]--; 30 sum++; 31 } 32 } 33 for(int i=0;i<7;i++) 34 if(cnt1[27+i]>=3)sum++; 35 if(sum==4)return 1; 36 return 0; 37 } 38 int jug() 39 { 40 int cnt1[35]; 41 for(int i=0;i<34;i++) 42 cnt1[i]=cnt[i]; 43 for(int i=0;i<34;i++) 44 { 45 if(cnt[i]>=2) 46 { 47 cnt[i]-=2; 48 if(ju()){ cnt[i]+=2;return 1;} 49 cnt[i]+=2; 50 } 51 } 52 return 0; 53 } 54 struct A{ 55 int id; 56 char ch; 57 bool operator <(A z) 58 { 59 if(ch!=z.ch)return ch<z.ch; 60 return id<z.id; 61 } 62 }Q[35]; 63 int main() 64 { 65 char s[3]; 66 while(scanf("%s",s)!=EOF) 67 { int t=s[0]-'1'; 68 memset(cnt,0,sizeof(cnt)); 69 if(s[1]=='m')t+=0; 70 else if(s[1]=='s')t+=9; 71 else if(s[1]=='p')t+=18; 72 else t+=27; 73 cnt[t]++; 74 for(int i=2;i<=13;i++) 75 { 76 scanf("%s",s); 77 t=s[0]-'1'; 78 if(s[1]=='m')t+=0; 79 else if(s[1]=='s')t+=9; 80 else if(s[1]=='p')t+=18; 81 else t+=27; 82 cnt[t]++; 83 } 84 int sum=0; 85 for(int i=0;i<34;i++) 86 { 87 cnt[i]++; 88 if(cnt[i]<=4&&jug()) 89 ant[++sum]=i; 90 cnt[i]--; 91 } 92 int zzz=0; 93 for(int i=1;i<=sum;i++) 94 { 95 Q[++zzz].id=ant[i]%9; 96 if(ant[i]/9==0)Q[zzz].ch='m'; 97 else if(ant[i]/9==1)Q[zzz].ch='s'; 98 else if(ant[i]/9==2)Q[zzz].ch='p'; 99 else Q[zzz].ch='z';} 100 sort(Q+1,Q+1+zzz); 101 for(int i=1;i<=zzz;i++) 102 cout<<Q[i].id+1<<Q[i].ch<<endl; 103 } 104 }