Chinese Mahjong

题意:

给出13张牌,判断是否听牌

思路:

一共34种牌,一一枚举,看是否会胡

每成一个序列use就加相应个数,如果use可达14个就可胡牌

代码:

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
using namespace std;  

const char* mahjong[] = {"1T", "2T", "3T", "4T", "5T", "6T", "7T", "8T", "9T",  
	"1S", "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S",  
	"1W", "2W", "3W", "4W", "5W", "6W", "7W", "8W", "9W",  
	"DONG", "NAN", "XI", "BEI", "ZHONG", "FA", "BAI"              
};   

int cnt[35]; 
int use;    
bool ok;
int change(char* p) {
	for(int i=0; i<34; i++)
		if(strcmp(p, mahjong[i]) == 0) return i;
}

bool judge(int i) {
	if(0<=i && i<=6) return true;
	if(9<=i && i<=15) return true;
	if(18<=i && i<=24) return true;
	return false;
}

bool dfs(int cur) {
	if(use == 14) {
		ok = true;
		return true;
	}
	if(cur >= 34) return false;
	if(cnt[cur] == 0)  return dfs(cur+1);//这里要注意只有当这种牌用完全部配对了才能进入下一个牌
	bool ok2 = false;
	if(cnt[cur] >= 3) {
		cnt[cur] -= 3;
		use += 3;
		if(dfs(cur)) ok2 = true;
		cnt[cur] += 3;
		use -= 3;
	}
	if(!ok2 && judge(cur) && cnt[cur] && cnt[cur+1] && cnt[cur+2]) {
		cnt[cur]--, cnt[cur+1]--, cnt[cur+2]--;
		use += 3;
		if(dfs(cur)) ok2 = true;
		use -= 3;
		cnt[cur]++, cnt[cur+1]++, cnt[cur+2]++;
	}

	return ok2;
}	

int main() {
	char mj[10];
	int kase=0;
	while(scanf("%s", mj) && strcmp("0", mj)) {
		printf("Case %d:", ++kase);
		memset(cnt, 0, sizeof(cnt));
		++cnt[change(mj)];
		ok = false;
		for(int i=0; i<12; i++) {
			scanf("%s", mj);
			++cnt[change(mj)];
		}
		for(int i=0; i<34; i++) {
			if(cnt[i] == 4) continue;
			cnt[i]++;
			for(int j=0; j<34; j++) {
				use = 0;
				bool ok3 = false;
				if(cnt[j] >= 2) {
					cnt[j] -= 2;
					use += 2;
					if(dfs(0)) {
						ok3 =  true;
						printf(" %s", mahjong[i]);
					}
					cnt[j]+=2;
				}
			
				if(ok3) break;
			}
		
			cnt[i]--;
		}
	
		if(ok) printf("\n");
		else printf(" Not ready\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值