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.)

 
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):
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL; const int MAXN = ; struct TILES {
int P[MAXN], M[MAXN], S[MAXN], C[MAXN]; void init() {
#define CL(a) memset(a, 0, sizeof(a))
CL(P), CL(M), CL(S), CL(C);
} void read() {
char str[];
for(int i = ; i < ; ++i) {
scanf("%s", str);
switch(str[]) {
case 'p':++P[str[] - ''];break;
case 'm':++M[str[] - ''];break;
case 's':++S[str[] - ''];break;
case 'c':++C[str[] - ''];break;
}
}
} bool special_judge1() {
int cnt = ;
for(int i = ; i <= ; ++i) {
cnt += (M[i] == );
cnt += (S[i] == );
cnt += (P[i] == );
cnt += (C[i] == );
}
return cnt == ;
} bool special_judge2() {
bool eyes = false;
for(int i = ; i <= ; ++i) {
if(C[i] == || C[i] > ) return false;
if(C[i] == ) eyes = true;
}
if(M[] == || M[] > ) return false;
if(M[] == || M[] > ) return false;
if(S[] == || S[] > ) return false;
if(S[] == || S[] > ) return false;
if(P[] == || P[] > ) return false;
if(P[] == || P[] > ) return false;
if(M[] == || M[] == ) eyes = true;
if(S[] == || S[] == ) eyes = true;
if(P[] == || P[] == ) eyes = true;
return eyes;
} int UP[MAXN], UM[MAXN], US[MAXN]; bool isWin() {
int x;
for(int i = ; i <= ; ++i) {
if(P[i] - UP[i] >= ) UP[i] += ;
if(S[i] - US[i] >= ) US[i] += ;
if(M[i] - UM[i] >= ) UM[i] += ;
x = P[i] - UP[i];
if(x != ) {
UP[i] += x;
if((UP[i + ] += x) > P[i + ]) return false;
if((UP[i + ] += x) > P[i + ]) return false;
}
x = S[i] - US[i];
if(x != ) {
US[i] += x;
if((US[i + ] += x) > S[i + ]) return false;
if((US[i + ] += x) > S[i + ]) return false;
}
x = M[i] - UM[i];
if(x != ) {
UM[i] += x;
if((UM[i + ] += x) > M[i + ]) return false;
if((UM[i + ] += x) > M[i + ]) return false;
}
}
return true;
} bool judge() {
if(special_judge1() || special_judge2()) return true;
bool eyes = false;
for(int i = ; i <= ; ++i) {
if(C[i] == ) {
if(!eyes) eyes = true;
else return false;
}
if(C[i] == || C[i] == ) return false;
}
if(eyes) {
CL(UP), CL(UM), CL(US);
return isWin();
}
for(int i = ; i <= ; ++i) {
if(P[i] >= ) {
CL(UP), CL(UM), CL(US);
UP[i] = ;
if(isWin()) return true;
}
}
for(int i = ; i <= ; ++i) {
if(S[i] >= ) {
CL(UP), CL(UM), CL(US);
US[i] = ;
if(isWin()) return true;
}
}
for(int i = ; i <= ; ++i) {
if(M[i] >= ) {
CL(UP), CL(UM), CL(US);
UM[i] = ;
if(isWin()) return true;
}
}
return false;
} vector<int> ans2;
vector<char> ans1; void solve() {
ans1.clear();
ans2.clear();
for(int i = ; i <= ; ++i) {
++M[i];
if(M[i] <= && judge()) {
ans1.push_back('m');
ans2.push_back(i);
}
--M[i];
}
for(int i = ; i <= ; ++i) {
++S[i];
if(S[i] <= && judge()) {
ans1.push_back('s');
ans2.push_back(i);
}
--S[i];
}
for(int i = ; i <= ; ++i) {
++P[i];
if(P[i] <= && judge()) {
ans1.push_back('p');
ans2.push_back(i);
}
--P[i];
}
for(int i = ; i <= ; ++i) {
++C[i];
if(C[i] <= && judge()) {
ans1.push_back('c');
ans2.push_back(i);
}
--C[i];
}
} void print() {
int len = ans1.size();
if(len == ) {
puts("Nooten");
return ;
}
printf("%d", len);
for(int i = ; i < len; ++i)
printf(" %d%c", ans2[i], ans1[i]);
puts("");
}
} G; int main() {
int T;
scanf("%d", &T);
while(T--) {
G.init();
G.read();
G.solve();
G.print();
}
}

HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)的更多相关文章

  1. HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )

    Sum of divisors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. HDU 4433 locker 2012 Asia Tianjin Regional Contest 减少国家DP

    意甲冠军:给定的长度可达1000数的顺序,图像password像锁.可以上下滑动,同时会0-9周期. 每个操作.最多三个数字连续操作.现在给出的起始序列和靶序列,获得操作的最小数量,从起始序列与靶序列 ...

  3. HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)

    Problem Description In this problem, you are given several strings that contain only digits from '0' ...

  4. HDU 4433 locker(DP)(2012 Asia Tianjin Regional Contest)

    Problem Description A password locker with N digits, each digit can be rotated to 0-9 circularly.You ...

  5. HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)

    Problem Description There's a queue obeying the first in first out rule. Each time you can either pu ...

  6. HDU 3721 Building Roads (2010 Asia Tianjin Regional Contest) - from lanshui_Yang

    感慨一下,区域赛的题目果然很费脑啊!!不过确实是一道不可多得的好题目!! 题目大意:给你一棵有n个节点的树,让你移动树中一条边的位置,即将这条边连接到任意两个顶点(边的大小不变),要求使得到的新树的直 ...

  7. HDU 3726 Graph and Queries(平衡二叉树)(2010 Asia Tianjin Regional Contest)

    Description You are given an undirected graph with N vertexes and M edges. Every vertex in this grap ...

  8. HDU 4468 Spy(KMP+贪心)(2012 Asia Chengdu Regional Contest)

    Description “Be subtle! Be subtle! And use your spies for every kind of business. ”― Sun Tzu“A spy w ...

  9. HDU 4467 Graph(图论+暴力)(2012 Asia Chengdu Regional Contest)

    Description P. T. Tigris is a student currently studying graph theory. One day, when he was studying ...

随机推荐

  1. c语言描述的静态查找表

    顺序表的查找: 直接循环依次和目标比较就行 有序表的查找(二分查找): int search(SS *T,Type key){ int mid; ; int high=T.length; while( ...

  2. Spring框架中的IOC?

    Spring中的org.springframework.beans包和org.SpringframeWork.context包构成了Spring框架IOC容器的基础.BeanFactory接口提供了一 ...

  3. Vue组件:组件的动态添加与删除

    一.实现效果 二.实现代码 HelloWorld.vue <template> <div class="hello"> <child-page v-f ...

  4. 构建高可靠hadoop集群之4-权限指引

    此文翻译自http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html ...

  5. ArrayList调用remove(int index)抛出UnsupportedOperationException问题分析以及解决记录

    使用Arrays转数组成为List后,不能调用add(...)和remove(...)方法,此时如果调用就会抛出UnsupportedOperationException异常 原因 其实Arrays. ...

  6. sql sever 基础 建表

    ---恢复内容开始--- SQL Sever 基础以创建银行数据库bankDB为案例 1.创建数据库 1-1 创建文件夹用以存放数据库 1-2 创建建库bankDB 2.创建数据库 2-1.创建用户信 ...

  7. Linux系统磁盘管理

    1 Linux磁盘管理体系简介 Linux磁盘管理分为五个步骤:首先在服务器上添加相应的硬盘(如/dev/sda.sdb.sdc等),对全新的服务器(即没有操作系统)做硬RAID0.RAID1.RAI ...

  8. POCO TCPServer 解析

    POCO C++ Libraries提供一套 C++ 的类库用以开发基于网络的可移植的应用程序,功能涉及线程.文件.流,网络协议包括:HTTP.FTP.SMTP 等,还提供 XML 的解析和 SQL ...

  9. ethereum Pet Shop

    在部署宠物商店时遇到的一些坑,给大家总结一下,以免大家多走弯路 转载的地址(详细):https://steemit.com/cn/@lucia3/ethereum-pet-shop 启动"n ...

  10. 系统编程.py(多进程与多线程干货)

    1.并发与并行* 多个任务轮换在CPU上跑叫并发* 多个任务在多个CPU上跑,没有交替执行的* 状态叫并行.通常情况下都是并发,即使是多核.* 而控制进程先执行谁后执行谁通过操作系统的调度算法.目前已 ...