0
点赞
收藏
分享

微信扫一扫

UVA - 11210 Chinese Mahjong 枚举


题目大意:给出13张牌,问由这13张牌组成的牌型能否听牌

解题思路:枚举每一张牌,将其代入,看能否能胡,如果能胡的话,就表示这张是所听的牌。

判断能否能胡的话,用回溯的方法进行处理。先处理对子,因为必有一个对子的,然后再处理刻子和顺子

#include<cstdio>
#include<cstring>
const char *majiang[] = {"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","XI","NAN","BEI","ZHONG","FA","BAI"};
#define maxn 40
#define maxm 15
int temp[maxn];
char t[10];
int M[maxm];

int change() {
	for(int i = 0; i < 34; i++)
		if(strcmp(majiang[i],t) == 0)
			return i;
	return -1;
}

bool judge(int times) {

	if(times == 4)
		return true;

	for(int i = 0; i < 34; i++) 
		if(temp[i] >= 3) {
			temp[i] -= 3;
			if( judge(times+1) )
				return true;
			temp[i] += 3;	
		}

	for(int i = 0; i <= 24 ; i++)
		if(i % 9 <= 6 && temp[i] && temp[i+1] && temp[i + 2]) {
			temp[i]--;temp[i+1]--;temp[i+2]--;
			if( judge(times + 1))
				return true;
			temp[i]++;temp[i+1]++;temp[i+2]++;	
		}
	return false;
}

bool check() {
	for(int i = 0; i < 34; i++) {
		if(temp[i] >= 2) {
			temp[i] -= 2;
			if( judge(0) )
				return true;
			temp[i] += 2;
		}
	}
	return false;

}
void DFS() {

	bool flag = false;
	for(int i = 0; i < 34; i++) {
		memset(temp,0,sizeof(temp));
		for(int j = 0; j < 13; j++)
			temp[M[j]]++;	
		if(temp[i] >= 4)
			continue;
		temp[i]++;
		if(check()) {
			flag = true;
			printf(" %s",majiang[i]);
		}
		temp[i]--;
	}
	if(!flag)
		printf(" Not ready");
	printf("\n");
}

int main() {
	int mark = 1;
	while(scanf("%s",t)) {
		if(t[0] == '0')
			break;	
		M[0] = change();
		for(int i = 1; i < 13; i++) {
			scanf("%s",t);
			M[i] = change();
		}
		printf("Case %d:",mark++);
		DFS();
	}
	return 0;
}



举报

相关推荐

0 条评论