Chinese Mahjong

题意:

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

思路:

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

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

代码:

#include  
#include  
#include  
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;
}


你可能感兴趣的:(寒假训练,暴力枚举)