Chinese Mahjong

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=456&problem=2151&mosmsg=Submission+received+with+ID+18761382

←_←习得此题,对麻将便略知一二。原来“和”需要一个将、0个或者多个刻子和0个或者多个顺子,←_← 若拿到一张牌能“和“了,则称听了这张牌。

例如1S 1S 2S 2S 2S 3S 3S 3S 7S 8S 9S FA FA

只要摸到1S 4S FA其中一个就可以和了,则称手牌听了1S 4S FA


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<cstring> 
const char* cards[] = {
	"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 c[34];
int convert(char *s)
{
	for (int i = 0; i<34; i++)
		if (strcmp(cards[i], s) == 0)
			return i;
	return -1;

}
bool search(int dep)
{
	for (int i = 0; i<34; i++)if (c[i] >= 3)
	{
		if (dep == 3)return true;
		c[i] -= 3;
		if (search(dep + 1))return true;
		c[i] += 3;
	}
	for (int i = 0; i <= 24; i++)if (c[i] >= 1 && i % 9 <= 6 && c[i + 1] >= 1 && c[i + 2] >= 1)
	{
		if (dep == 3)return true;
		c[i]--; c[i + 1]--; c[i + 2]--;
		if (search(dep + 1))return true;
		c[i]++; c[i + 1]++; c[i + 2]++;
	}
	return false;
}

bool check()
{
	for (int i = 0; i<34; i++)
	{
		if (c[i] >= 2)
		{
			c[i] -= 2;
			if (search(0))return true;
			c[i] += 2;
		}
	}
	return false;
}
using namespace std;
int main()
{
	int mj[13];		char str[7];
	bool ok; int kase = 0;
	while (scanf("%s", &str) == 1)
	{
		ok = false;
		if (str[0] == '0')break;
		printf("Case %d:", ++kase);
	
		mj[0] = convert(str);
		for (int i = 1; i<13; i++) {
			scanf("%s", &str); mj[i] = convert(str);
		}
		for (int i = 0; i<34; i++)
		{
	memset(c, 0, sizeof(c));
			for (int j = 0; j<13; j++)
				c[mj[j]]++;

			if (c[i] >= 4)continue;

			c[i]++;
			if (check())
			{
				ok = true;
				printf(" %s", cards[i]);
			}
			c[i]--;
		}
		if (!ok)printf(" Not ready");
		printf("\n");
	}


	return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值