题意:如果摸到的14张麻将,可以组成4副三张麻将连续或者相同的,以及两个一样的就能获胜。

思路:直接暴力枚举每种可以摸到的牌型,用dfs判断当前拿到的14张牌型能否获胜。

如果搜索时不优化会超时,如果你选择了第cur张牌,那么你下次不必再选择cur以前的牌,因为会造成重复搜索。加上这个剪枝就能过掉。我还自己加了一个剪枝:先排序,然后如果组合到第cur张牌,前面还有牌没有组合,说明不可能组合完,因为每张牌只会和它自身以及比它更大的牌组合。

字符的处理:s、b、c看做0,1,2,那么1s就表示10,5b表示51,就能愉快地转换成数字了。

AC代码:78ms

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 100+5;
char p[] = {'s', 'b', 'c'};
int vis[maxn], cnt[maxn], a[20];
bool dfs(int k, int cur) {
	for(int i = 0; i < cur; ++i) { //剪枝
		if(cnt[a[i]]) return false;
	}
	if(k == 5) return true;
	if(k == 0) {
		for(int i = 0; i < 14; ++i) {
			int x = a[i];
			if(cnt[x] >= 2 && !vis[x]) {
				vis[x] = 1;
				cnt[x] -= 2;
				if(dfs(k+1, cur)) return true;
				cnt[x] += 2;
			}
		}
	}
	else {
		for(int i = cur; i < 14; ++i) {
			int x = a[i];
			//取三个一样的
			if(cnt[x] >= 3) {
				cnt[x] -= 3;
				if(dfs(k+1, i)) return true;
				cnt[x] += 3;
			}
			//取三个连续的
			int y = x / 10, z = x % 10;
			if(y + 2 <= 9) {
				int flag = 1;
				for(int j = 0; j < 3; ++j) {
					if(!cnt[(y+j)*10+z]) {
						flag = 0;
						break;
					}
				}
				if(flag) {
					for(int j = 0; j < 3; ++j) cnt[(y+j)*10+z]--;
					if(dfs(k+1, i)) return true;
					for(int j = 0; j < 3; ++j) cnt[(y+j)*10+z]++;
				}
			}
		}
	}
	return false;
}

int main() {
	char ma[5];
	int T, kase = 1;
	scanf("%d", &T);
	while(T--) {
		memset(cnt, 0, sizeof(cnt));
		for(int i = 0; i < 13; ++i) {
			scanf("%s", ma);
			for(int j = 0; j < 3; ++j) {
				if(ma[1] == p[j]) {
					a[i] = (ma[0]-'0')*10+j;
					cnt[a[i]]++;
				}
			}
		}
		int old[maxn] , b[maxn];
		memcpy(old, cnt, sizeof(cnt));
		memcpy(b, a, sizeof(a));
		printf("Case %d:", kase++);
		int ans = 0;
		for(int i = 0; i <= 2; ++i)
			for(int j = 1; j <= 9; ++j) {
				int x = j * 10 + i;
				if(cnt[x] == 4) continue;
				memset(vis, 0, sizeof(vis));
				memcpy(cnt, old, sizeof(old));
				memcpy(a, b, sizeof(a));
				a[13] = x;
				sort(a, a+14);
				cnt[x]++;
				if(dfs(0, 0)) {
					++ans;
					printf(" %d%c", j, p[i]);
				}
			}
		if(!ans) printf(" None");
		printf("\n");
	}
	return 0;
}

如有不当之处欢迎指出!

HDU - 3391 C - Mahjong的更多相关文章

  1. HDU 5379 Mahjong tree(dfs)

    题目链接:pid=5379">http://acm.hdu.edu.cn/showproblem.php? pid=5379 Problem Description Little su ...

  2. HDU 5379 Mahjong tree(树的遍历&amp;组合数学)

    本文纯属原创,转载请注明出处.谢谢. http://blog.csdn.net/zip_fan 题目传送门:http://acm.hdu.edu.cn/showproblem.php? pid=537 ...

  3. Hdu 5379 Mahjong tree (dfs + 组合数)

    题目链接: Hdu 5379 Mahjong tree 题目描述: 给出一个有n个节点的树,以节点1为根节点.问在满足兄弟节点连续 以及 子树包含节点连续 的条件下,有多少种编号方案给树上的n个点编号 ...

  4. HDU 4431 Mahjong (DFS,暴力枚举,剪枝)

    题意:给定 13 张麻将牌,问你是不是“听”牌,如果是输出“听”哪张. 析:这个题,很明显的暴力,就是在原来的基础上再放上一张牌,看看是不是能胡,想法很简单,也比较好实现,结果就是TLE,一直TLE, ...

  5. 2015多校第7场 HDU 5379 Mahjong tree 构造,DFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5379 题意:一颗n个节点n-1条边的树,现在要给每个节点标号(1~n),要求:(1)每一层的兄弟节点的 ...

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

    Problem Description Japanese Mahjong is a four-player game. The game needs four people to sit around ...

  7. HDU 5379——Mahjong tree——————【搜索】

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. 2015 Multi-University Training Contest 7 hdu 5379 Mahjong tree

    Mahjong tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  9. HDU 4431 Mahjong 模拟

    http://acm.hdu.edu.cn/showproblem.php?pid=4431 不能说是水题了,具体实现还是很恶心的...几乎优化到哭但是DFS(还加了几个剪枝)还是不行...搜索一直T ...

随机推荐

  1. wstring操作与普通段字符操作对照表

    字符分类:   宽字符函数普通C函数描述   iswalnum()   isalnum()   测试字符是否为数字或字母   iswalpha()   isalpha()   测试字符是否是字母    ...

  2. php 在foreach中循环数组的时候添加元素的属性

    foreach($arr as $k => &$v){ //注意,由于上面遍历的时候写了地址传值符&, //所以下面可以直接给$v 赋值;如果不写&符号,下面这样写是没有 ...

  3. 【nginx】nginx解决跨域详解

    使用场景:本地运行一个项目,但是要访问外域的api接口,存在跨域问题,解决方式有很多,但我尝试用nginx解决,搜索了网上文章后再加上尝试终于成功, 其中一些注意事项和大家分享一下. 一.window ...

  4. 合理使用软引用和弱引用,提升JVM内存使用性能

    在项目运行时,OOM异常是比较处理的,因为从日志看出的发生异常的代码点可能仅仅是最后一根稻草,从中可能未必能发现OOM的原因,而且OOM未必是固定重现的. 上医治未病,与其等OOM问题发生时再通过看日 ...

  5. redis数据类型-集合类型

    集合类型 在集合中的每个元素都是不同的,且没有顺序. 一个集合类型(set)键可以存储至多2 32-1个(相信这个数字对大家来说已经很熟悉了)字符串. 集合类型的常用操作是向集合中加入或删除元素.判断 ...

  6. Eclipse运行Java简单实例

    运行eclipse前首先配置好JDK环境变量等  双击这句话可跳转配置环境变量详细步骤 运行eclipse软件 1.File菜单-New - project 2.Java Project - Next ...

  7. Python之Django rest_Framework补充

    一.什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为"表征状态转移" ...

  8. 性能测试监控:Jmeter +InfluxDB +collectd +Grafana

    虚拟机ip 192.168.180.128 Influxdb Influxdb是一个开源的分布式时序.时间和指标数据库,使用go语言编写,无需外部依赖. 它有三大特性: 时序性(Time Series ...

  9. WebService学习------小实例开发(号码归属地查询)

    1.WebService简介: WebService是一种跨平台,跨语言的,可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.通过SOAP在Web上提 ...

  10. jQuery应用操作之---表格

    示例: <table> <thread> <tr><th>姓名</th><th>性别</th><th>暂 ...