HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)

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.)
#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)的更多相关文章
- 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) ...
- HDU 4433 locker 2012 Asia Tianjin Regional Contest 减少国家DP
意甲冠军:给定的长度可达1000数的顺序,图像password像锁.可以上下滑动,同时会0-9周期. 每个操作.最多三个数字连续操作.现在给出的起始序列和靶序列,获得操作的最小数量,从起始序列与靶序列 ...
- HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)
Problem Description In this problem, you are given several strings that contain only digits from '0' ...
- 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 ...
- 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 ...
- HDU 3721 Building Roads (2010 Asia Tianjin Regional Contest) - from lanshui_Yang
感慨一下,区域赛的题目果然很费脑啊!!不过确实是一道不可多得的好题目!! 题目大意:给你一棵有n个节点的树,让你移动树中一条边的位置,即将这条边连接到任意两个顶点(边的大小不变),要求使得到的新树的直 ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- ios学习路线—Objective-C(堆(heap)和栈(stack))
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话就 ...
- kali linux 中文出现乱码问题的解决
确定locales已经安装,用”apt-get install locales”命令:之后可用”locale -a”查看当前系统支持的字符集. 1. 在命令行输入”dpkg-reconfigure l ...
- 20181009noip HZ EZ两校联考sum(莫队,组合数学)
题面戳这里 思路: noip考莫队???!!! 考场上死活没往这方面想啊!!!数据分治忘写endl50pts滚粗了 这里每个询问都有n,m两个参数 我们可以把它看做常规莫队中的l和r 然后利用组合数的 ...
- Maven 运行启动时****找不到符号*com.xxx.user.java
Maven 运行启动时****找不到符号*com.xxx.user.java maven项目更改后没有安装 (install) 重新安装解决问题!
- jsp+spring+jquery+ajax的简单例子
初学b/s编程,花费了许多时间,进度颇慢! 不过终于完成了一个简单的例子: jsp代码 <%@ page language="java" contentType=" ...
- oracle的事务隔离级别和读一致性
oracle提供了三个隔离级别: 1.读提交 ,简而言之只能读取语句开始执行前提交的数据 2.串行,这个好理解,就是事务串行运行,避免经典的三个场景-脏读.不可重复读.幻读. 3.只读,oracle已 ...
- 关于J2EE里面getContextPath()和getRealPath()的区别
一直老搞不清楚这两个方法的区别,只知道他们都是拿来获取地址的.今天特意写了个小demo试了一下,代码如下: @Override protected void service(HttpServletRe ...
- CentOS查看占用端口并关闭
1.查看占用的端口号 netstat -lnp|grep 80 #80 是你需要查看的端口号 二.查看进程的详细信息 ps 29280 #查看进行信息,是否是自己要找的进程 三.杀掉进程 kill ...
- CentOS7.2中安装MongoDB
MongoDB是由C++编写的NoSQL的分布式文件数据库,用的json格式的k-value存储方式. MongoDB官网 https://www.mongodb.com 一.下载和安装 下载完后文件 ...
- redis之哨兵(Sentinel)
Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能. 而 ...