Problem Description
Japanese Mahjong is a four-player game. The game needs four people to sit around a desk and play with a set of Mahjong tiles. A set of Mahjong tiles contains four copies of the tiles described next:
One to nine Man, which we use 1m to 9m to represent;
One to nine Sou, which we use 1s to 9s to represent;
One to nine Pin, which we use 1p to 9p to represent;
Character tiles, which are:Ton, Nan, Sei, Pei, Haku, Hatsu, Chun, which we use 1c to 7c to represent.
A winning state means a set of 14 tiles that normally contains a pair of same tiles (which we call "eyes") and four melds. A meld is formed by either three same tiles(1m, 1m, 1m or 2c, 2c, 2c for example) or three continuous non-character tiles(1m, 2m, 3m or 5s, 6s, 7s for example).
However, there are two special winning states that are different with the description above, which are:
"Chii Toitsu", which means 7 different pairs of tiles;
"Kokushi Muso", which means a set of tiles that contains all these tiles: 1m, 9m, 1p, 9p, 1s, 9s and all 7 character tiles. And the rest tile should also be one of the 13 tiles above.
And the game starts with four players receiving 13 tiles. In each round every player must draw one tile from the deck one by one. If he reaches a winning state with these 14 tiles, he can say "Tsu Mo" and win the game. Otherwise he should discard one of his 14 tiles. And if the tile he throws out can form a winning state with the 13 tiles of any other player, the player can say "Ron" and win the game.
Now the question is, given the 13 tiles you have, does there exist any tiles that can form a winning state with your tiles?
(Notes: Some of the pictures and descriptions above come from Wikipedia.)
One to nine Man, which we use 1m to 9m to represent;
One to nine Sou, which we use 1s to 9s to represent;
One to nine Pin, which we use 1p to 9p to represent;
Character tiles, which are:Ton, Nan, Sei, Pei, Haku, Hatsu, Chun, which we use 1c to 7c to represent.
A winning state means a set of 14 tiles that normally contains a pair of same tiles (which we call "eyes") and four melds. A meld is formed by either three same tiles(1m, 1m, 1m or 2c, 2c, 2c for example) or three continuous non-character tiles(1m, 2m, 3m or 5s, 6s, 7s for example).
However, there are two special winning states that are different with the description above, which are:
"Chii Toitsu", which means 7 different pairs of tiles;
"Kokushi Muso", which means a set of tiles that contains all these tiles: 1m, 9m, 1p, 9p, 1s, 9s and all 7 character tiles. And the rest tile should also be one of the 13 tiles above.
And the game starts with four players receiving 13 tiles. In each round every player must draw one tile from the deck one by one. If he reaches a winning state with these 14 tiles, he can say "Tsu Mo" and win the game. Otherwise he should discard one of his 14 tiles. And if the tile he throws out can form a winning state with the 13 tiles of any other player, the player can say "Ron" and win the game.
Now the question is, given the 13 tiles you have, does there exist any tiles that can form a winning state with your tiles?
(Notes: Some of the pictures and descriptions above come from Wikipedia.)
Input
The input data begins with a integer T(1≤T≤20000). Next are T cases, each of which contains 13 tiles. The description of every tile is as above.
Output
For each cases, if there actually exists some tiles that can form a winning state with the 13 tiles given, print the number first and then print all those tiles in order as the description order of tiles above. Otherwise print a line "Nooten"(without quotation marks).
题目大意:给你十三张麻将牌,问你再加一张什么牌,可以胡。胡的方法:1、有一对眼,剩下的是顺子和三张相同的牌组成14张牌。2、有7个对子(4个相同的牌不能算两对,这个题目似乎没有说,就是看漏了这个条件WA了一个多小时……我就说怎么题目说两个我只看到一个呢……)。3、十三幺。
思路:枚举每一张牌,判断能否获胜。条件2、3特判即可。对于条件1,如果有某张字牌只有1张或4张,或有两个以上的字牌有2张,输出错误。然后枚举眼(对子),然后对每一种牌(万子、筒子、束子)分配从1~9循环,若某张牌 i 剩下3张或以上,那么把三张 i 作为三个相同的牌拿掉(如果这牌是能获胜的,那么枚举到 i ,i 前面的牌都已经被判断后拿掉了,那么如果 i 可以作为顺子被拿掉,那么 i+1 和 i+2 肯定都有3张或以上)。若小于三张,则把 i 、 i+1 、 i+2 拿掉。如果拿不掉则判断不能获胜。全部拿掉之后判断获胜。那些TLE的人肯定是姿势不对。
代码(265MS):
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 typedef long long LL; 8 9 const int MAXN = 13; 10 11 struct TILES { 12 int P[MAXN], M[MAXN], S[MAXN], C[MAXN]; 13 14 void init() { 15 #define CL(a) memset(a, 0, sizeof(a)) 16 CL(P), CL(M), CL(S), CL(C); 17 } 18 19 void read() { 20 char str[5]; 21 for(int i = 0; i < 13; ++i) { 22 scanf("%s", str); 23 switch(str[1]) { 24 case 'p':++P[str[0] - '0'];break; 25 case 'm':++M[str[0] - '0'];break; 26 case 's':++S[str[0] - '0'];break; 27 case 'c':++C[str[0] - '0'];break; 28 } 29 } 30 } 31 32 bool special_judge1() { 33 int cnt = 0; 34 for(int i = 1; i <= 9; ++i) { 35 cnt += (M[i] == 2); 36 cnt += (S[i] == 2); 37 cnt += (P[i] == 2); 38 cnt += (C[i] == 2); 39 } 40 return cnt == 7; 41 } 42 43 bool special_judge2() { 44 bool eyes = false; 45 for(int i = 1; i <= 7; ++i) { 46 if(C[i] == 0 || C[i] > 2) return false; 47 if(C[i] == 2) eyes = true; 48 } 49 if(M[1] == 0 || M[1] > 2) return false; 50 if(M[9] == 0 || M[9] > 2) return false; 51 if(S[1] == 0 || S[1] > 2) return false; 52 if(S[9] == 0 || S[9] > 2) return false; 53 if(P[1] == 0 || P[1] > 2) return false; 54 if(P[9] == 0 || P[9] > 2) return false; 55 if(M[1] == 2 || M[9] == 2) eyes = true; 56 if(S[1] == 2 || S[9] == 2) eyes = true; 57 if(P[1] == 2 || P[9] == 2) eyes = true; 58 return eyes; 59 } 60 61 int UP[MAXN], UM[MAXN], US[MAXN]; 62 63 bool isWin() { 64 int x; 65 for(int i = 1; i <= 9; ++i) { 66 if(P[i] - UP[i] >= 3) UP[i] += 3; 67 if(S[i] - US[i] >= 3) US[i] += 3; 68 if(M[i] - UM[i] >= 3) UM[i] += 3; 69 x = P[i] - UP[i]; 70 if(x != 0) { 71 UP[i] += x; 72 if((UP[i + 1] += x) > P[i + 1]) return false; 73 if((UP[i + 2] += x) > P[i + 2]) return false; 74 } 75 x = S[i] - US[i]; 76 if(x != 0) { 77 US[i] += x; 78 if((US[i + 1] += x) > S[i + 1]) return false; 79 if((US[i + 2] += x) > S[i + 2]) return false; 80 } 81 x = M[i] - UM[i]; 82 if(x != 0) { 83 UM[i] += x; 84 if((UM[i + 1] += x) > M[i + 1]) return false; 85 if((UM[i + 2] += x) > M[i + 2]) return false; 86 } 87 } 88 return true; 89 } 90 91 bool judge() { 92 if(special_judge1() || special_judge2()) return true; 93 bool eyes = false; 94 for(int i = 1; i <= 7; ++i) { 95 if(C[i] == 2) { 96 if(!eyes) eyes = true; 97 else return false; 98 } 99 if(C[i] == 1 || C[i] == 4) return false; 100 } 101 if(eyes) { 102 CL(UP), CL(UM), CL(US); 103 return isWin(); 104 } 105 for(int i = 1; i <= 9; ++i) { 106 if(P[i] >= 2) { 107 CL(UP), CL(UM), CL(US); 108 UP[i] = 2; 109 if(isWin()) return true; 110 } 111 } 112 for(int i = 1; i <= 9; ++i) { 113 if(S[i] >= 2) { 114 CL(UP), CL(UM), CL(US); 115 US[i] = 2; 116 if(isWin()) return true; 117 } 118 } 119 for(int i = 1; i <= 9; ++i) { 120 if(M[i] >= 2) { 121 CL(UP), CL(UM), CL(US); 122 UM[i] = 2; 123 if(isWin()) return true; 124 } 125 } 126 return false; 127 } 128 129 vector<int> ans2; 130 vector<char> ans1; 131 132 void solve() { 133 ans1.clear(); 134 ans2.clear(); 135 for(int i = 1; i <= 9; ++i) { 136 ++M[i]; 137 if(M[i] <= 4 && judge()) { 138 ans1.push_back('m'); 139 ans2.push_back(i); 140 } 141 --M[i]; 142 } 143 for(int i = 1; i <= 9; ++i) { 144 ++S[i]; 145 if(S[i] <= 4 && judge()) { 146 ans1.push_back('s'); 147 ans2.push_back(i); 148 } 149 --S[i]; 150 } 151 for(int i = 1; i <= 9; ++i) { 152 ++P[i]; 153 if(P[i] <= 4 && judge()) { 154 ans1.push_back('p'); 155 ans2.push_back(i); 156 } 157 --P[i]; 158 } 159 for(int i = 1; i <= 7; ++i) { 160 ++C[i]; 161 if(C[i] <= 4 && judge()) { 162 ans1.push_back('c'); 163 ans2.push_back(i); 164 } 165 --C[i]; 166 } 167 } 168 169 void print() { 170 int len = ans1.size(); 171 if(len == 0) { 172 puts("Nooten"); 173 return ; 174 } 175 printf("%d", len); 176 for(int i = 0; i < len; ++i) 177 printf(" %d%c", ans2[i], ans1[i]); 178 puts(""); 179 } 180 } G; 181 182 int main() { 183 int T; 184 scanf("%d", &T); 185 while(T--) { 186 G.init(); 187 G.read(); 188 G.solve(); 189 G.print(); 190 } 191 }