11210 - Chinese Mahjong(dfs)

题目:11210 - Chinese Mahjong


题目大意:给出十三个麻将, 问再取哪一个能胡?把所有的情况列出来,并且按照题目要求的顺序。胡的条件需要一个而且仅一个对,然后剩下要么是三个相同的,要么是三个连续的(前提是后缀相同,并且只有 T, S, W在考虑范围内)


解题思路:把要取的情况一个个枚举出来,然后dfs, 找是否加入这个可以胡就可以了,找的话就三种情况去判断一下。但是要注意:三个连续要注意需要后缀相同,我这里是把麻将转成数字,然后统计这个麻将出现的次数,所以需要些边界的判断。


代码:

#include <stdio.h>
#include <string.h>

const int N = 35;
const char s[7][7] = {"DONG", "NAN", "XI", "BEI", "ZHONG", "FA", "BAI"};
int tile[N];
char str[N];

int handle () {

	if (str[0] >= '1' && str[0] <= '9') {

		int add;
		switch (str[1]) {

			case 'T': add = 0;break;
			case 'S': add = 9;break;
			case 'W': add = 18;break;
		}
		return add + str[0] - '0';
	} else {

		int i;
		for (i = 0; i < 7; i++)
			if (strcmp(str, s[i]) == 0)
				break;
		return 28 + i;
	}
}

bool dfs (int k, int flag) {

	if (k >= 14) {

		if (flag)
			return true;
		return false;
	}
	for (int i = 1; i < N; i++) {

		if (tile[i] >= 2 && !flag) {

			tile[i] -= 2;
			if (dfs (k + 2, 1)) {

				tile[i] += 2;
				return true;
			} 
			tile[i] += 2;
		}
		if (tile[i] >= 3) {

			tile[i] -= 3;
			if (dfs (k + 3, flag)) {

				tile[i] += 3;
				return true;
			}
			tile[i] += 3;
		}
		if ( (i > 7&& i < 10) || (i > 16 && i < 19) || i > 25)
			continue;
		if (tile[i] >= 1 && tile[i + 1] >= 1 && tile[i + 2] >= 1) {

			tile[i]--;
			tile[i + 1]--;
			tile[i + 2]--;
			if (dfs (k + 3, flag)) {

				tile[i]++;
				tile[i + 1]++;
				tile[i + 2]++;
				return true;
			}
			tile[i]++;
			tile[i + 1]++;
			tile[i + 2]++;
		}
	}
	return false;
}

int main () {

	int ans[N], k, cas = 0;
	while (scanf ("%s", str)) {

		memset (tile, 0, sizeof(tile));
		k = 0;
		if (str[0] == '0')
			break;
		tile[handle()]++;
		for (int i = 0; i < 12; i++) {

			scanf ("%s", str);
			tile[handle()]++;
		}

		for (int i = 1; i < N; i++) {

			if (tile[i] >= 4)
				continue;
			tile[i]++;
			if (dfs (0, 0))
				ans[k++] = i;
			tile[i]--;
		}
	
		printf ("Case %d: ", ++cas);
		if (!k) {

			printf ("Not ready\n");
			continue;
		}
		for (int i = 0; i < k; i++) {

			if (i < k - 1) {

				if (ans[i] >= 1 && ans[i] <= 9)
					printf ("%dT ", ans[i]);
				else if (ans[i] >= 10 && ans[i] <= 18)
					printf ("%dS ", ans[i]- 9);
				else if (ans[i] >= 19 && ans[i] <= 27)
					printf ("%dW ", ans[i] - 18);
				else
					printf ("%s ", s[ans[i] - 28]);
			} else {

				if (ans[i] >= 1 && ans[i] <= 9)              	
					printf ("%dT\n", ans[i]);
				else if (ans[i] >= 10 && ans[i] <= 18)          
					printf ("%dS\n", ans[i] - 9);
				else if (ans[i] >= 19 && ans[i] <= 27)
					printf ("%dW\n", ans[i] - 18);   
				else
					printf ("%s\n", s[ans[i] - 28]);
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值