UVA 11210 Chinese Mahjong

简单的深搜题目,但是代码写的有点冗杂,以后要注意精简代码了。

#include <stdio.h>
#include <string.h>
#include <string>
#include <set>
#include <vector>
using namespace std;

struct state{
	int T[10];
	int S[10];
	int W[10];

	int dong;
	int nan;
	int xi;
	int bei;
	int zhong;
	int fa;
	int bai;
};

set<string> visited;
bool find_target;
vector<string> answer;

string state2string(const struct state &sta){
	int i, j;
	string str, s;
	char buf[5];

	strcpy(buf, "1T");
	for(i=1; i<=9; i++){
		if(sta.T[i]){
			buf[0] = '0'+i;
			s.assign(buf);
			for(j=1; j<=sta.T[i]; j++)
				str = str+s;
		}
	}

	strcpy(buf, "1S");
	for(i=1; i<=9; i++){
		if(sta.S[i]){
			buf[0] = '0'+i;
			s.assign(buf);
			for(j=1; j<=sta.S[i]; j++)
				str = str+s;
		}
	}

	strcpy(buf, "1W");
	for(i=1; i<=9; i++){
		if(sta.W[i]){
			buf[0] = '0'+i;
			s.assign(buf);
			for(j=1; j<=sta.W[i]; j++)
				str = str+s;
		}
	}

	strcpy(buf, "D");
	s.assign(buf);
	for(i=1; i<=sta.dong; i++)
		str = str+s;

	strcpy(buf, "N");
	s.assign(buf);
	for(i=1; i<=sta.nan; i++)
		str = str+s;

	strcpy(buf, "X");
	s.assign(buf);
	for(i=1; i<=sta.xi; i++)
		str = str+s;

	strcpy(buf, "A");
	s.assign(buf);
	for(i=1; i<=sta.bei; i++)
		str = str+s;

	strcpy(buf, "Z");
	s.assign(buf);
	for(i=1; i<=sta.zhong; i++)
		str = str+s;

	strcpy(buf, "F");
	s.assign(buf);
	for(i=1; i<=sta.fa; i++)
		str = str+s;

	strcpy(buf, "B");
	s.assign(buf);
	for(i=1; i<=sta.bai; i++)
		str = str+s;

	return str;
}

void analyse(struct state &sta, char *str){
	if(0 == strcmp(str, "DONG")){
		sta.dong++;
		return;
	}

	if(0 == strcmp(str, "NAN")){
		sta.nan++;
		return;
	}

	if(0 == strcmp(str, "XI")){
		sta.xi++;
		return;
	}

	if(0 == strcmp(str, "BEI")){
		sta.bei++;
		return;
	}

	if(0 == strcmp(str, "ZHONG")){
		sta.zhong++;
		return;
	}

	if(0 == strcmp(str, "FA")){
		sta.fa++;
		return;
	}

	if(0 == strcmp(str, "BAI")){
		sta.bai++;
		return;
	}

	switch(str[1]){
	case 'T':
		sta.T[str[0]-'0']++;
		return;
	case 'S':
		sta.S[str[0]-'0']++;
		return;
	case 'W':
		sta.W[str[0]-'0']++;
		return;
	}

	printf("error!\n");
}

void dfs(const struct state &cur_sta, int pai_num){
	string hash_v;
	int i;
	struct state new_sta;

	if(find_target)
		return;

	hash_v = state2string(cur_sta);
	if(visited.find(hash_v) != visited.end())
		return;

	visited.insert(hash_v);

	if(0 == pai_num){
		find_target = true;
		return;
	}

	if(14 == pai_num){
		for(i=1; i<=9; i++){
			if(cur_sta.T[i] >= 2){
				new_sta = cur_sta;
				new_sta.T[i] -= 2;
				dfs(new_sta, 12);
			}
		}

		for(i=1; i<=9; i++){
			if(cur_sta.S[i] >= 2){
				new_sta = cur_sta;
				new_sta.S[i] -= 2;
				dfs(new_sta, 12);
			}
		}

		for(i=1; i<=9; i++){
			if(cur_sta.W[i] >= 2){
				new_sta = cur_sta;
				new_sta.W[i] -= 2;
				dfs(new_sta, 12);
			}
		}

		if(cur_sta.dong >= 2){
			new_sta = cur_sta;
			new_sta.dong -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.nan >= 2){
			new_sta = cur_sta;
			new_sta.nan -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.xi >= 2){
			new_sta = cur_sta;
			new_sta.xi -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.bei >= 2){
			new_sta = cur_sta;
			new_sta.bei -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.zhong >= 2){
			new_sta = cur_sta;
			new_sta.zhong -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.fa >= 2){
			new_sta = cur_sta;
			new_sta.fa -= 2;
			dfs(new_sta, 12);
		}

		if(cur_sta.bai >= 2){
			new_sta = cur_sta;
			new_sta.bai -= 2;
			dfs(new_sta, 12);
		}
		return;
	}

	for(i=1; i<=9; i++){
		if(cur_sta.T[i]){
			if(cur_sta.T[i]>=3){
				new_sta = cur_sta;
				new_sta.T[i] -= 3;
				dfs(new_sta, pai_num-3);
			}

			if(i<=7 && cur_sta.T[i] && cur_sta.T[i+1] && cur_sta.T[i+2]){
				new_sta = cur_sta;
				new_sta.T[i]--;
				new_sta.T[i+1]--;
				new_sta.T[i+2]--;
				dfs(new_sta, pai_num-3);
			}
		}
	}

	for(i=1; i<=9; i++){
		if(cur_sta.S[i]){
			if(cur_sta.S[i]>=3){
				new_sta = cur_sta;
				new_sta.S[i] -= 3;
				dfs(new_sta, pai_num-3);
			}

			if(i<=7 && cur_sta.S[i] && cur_sta.S[i+1] && cur_sta.S[i+2]){
				new_sta = cur_sta;
				new_sta.S[i]--;
				new_sta.S[i+1]--;
				new_sta.S[i+2]--;
				dfs(new_sta, pai_num-3);
			}
		}
	}

	for(i=1; i<=9; i++){
		if(cur_sta.W[i]){
			if(cur_sta.W[i]>=3){
				new_sta = cur_sta;
				new_sta.W[i] -= 3;
				dfs(new_sta, pai_num-3);
			}

			if(i<=7 && cur_sta.W[i] && cur_sta.W[i+1] && cur_sta.W[i+2]){
				new_sta = cur_sta;
				new_sta.W[i]--;
				new_sta.W[i+1]--;
				new_sta.W[i+2]--;
				dfs(new_sta, pai_num-3);
			}
		}
	}

	if(cur_sta.dong ==3){
		new_sta = cur_sta;
		new_sta.dong = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.nan ==3){
		new_sta = cur_sta;
		new_sta.nan = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.xi ==3){
		new_sta = cur_sta;
		new_sta.xi = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.bei ==3){
		new_sta = cur_sta;
		new_sta.bei = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.zhong ==3){
		new_sta = cur_sta;
		new_sta.zhong = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.fa ==3){
		new_sta = cur_sta;
		new_sta.fa = 0;
		dfs(new_sta, pai_num-3);
	}

	if(cur_sta.bai ==3){
		new_sta = cur_sta;
		new_sta.bai = 0;
		dfs(new_sta, pai_num-3);
	}

}

void func(const struct state &start_sta){
	struct state new_sta;
	int i;
	string str;
	char buf[50];
	static int case_n = 1;
	

	answer.clear();

	strcpy(buf, "1T");
	for(i=1; i<=9; i++){
		if(start_sta.T[i]<=3){
			new_sta = start_sta;
			new_sta.T[i]++;
			find_target = false;
			visited.clear();
			dfs(new_sta, 14);
			if(find_target){
				buf[0] = '0'+i;
				str.assign(buf);
				answer.push_back(str);
			}
		}
	}

	strcpy(buf, "1S");
	for(i=1; i<=9; i++){
		if(start_sta.S[i]<=3){
			new_sta = start_sta;
			new_sta.S[i]++;
			find_target = false;
			visited.clear();
			dfs(new_sta, 14);
			if(find_target){
				buf[0] = '0'+i;
				str.assign(buf);
				answer.push_back(str);
			}
		}
	}

	strcpy(buf, "1W");
	for(i=1; i<=9; i++){
		if(start_sta.W[i]<=3){
			new_sta = start_sta;
			new_sta.W[i]++;
			find_target = false;
			visited.clear();
			dfs(new_sta, 14);
			if(find_target){
				buf[0] = '0'+i;
				str.assign(buf);
				answer.push_back(str);
			}
		}
	}

	strcpy(buf, "DONG");
	str.assign(buf);
	if(start_sta.dong<=3){
		new_sta = start_sta;
		new_sta.dong++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "NAN");
	str.assign(buf);
	if(start_sta.nan<=3){
		new_sta = start_sta;
		new_sta.nan++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "XI");
	str.assign(buf);
	if(start_sta.xi<=3){
		new_sta = start_sta;
		new_sta.xi++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "BEI");
	str.assign(buf);
	if(start_sta.bei<=3){
		new_sta = start_sta;
		new_sta.bei++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "ZHONG");
	str.assign(buf);
	if(start_sta.zhong<=3){
		new_sta = start_sta;
		new_sta.zhong++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "FA");
	str.assign(buf);
	if(start_sta.fa<=3){
		new_sta = start_sta;
		new_sta.fa++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	strcpy(buf, "BAI");
	str.assign(buf);
	if(start_sta.bai<=3){
		new_sta = start_sta;
		new_sta.bai++;
		find_target = false;
		visited.clear();
		dfs(new_sta, 14);
		if(find_target){
			answer.push_back(str);
		}
	}

	printf("Case %d:", case_n++);
	if(0 == answer.size()){
		printf(" Not ready\n");
	}
	else{
		for(i=0; i<answer.size(); i++){
			printf(" %s", answer[i].c_str());
		}
		printf("\n");
	}

}

int main(void){
	int i;
	char buf[100];
	struct state sta;

	//freopen("input.dat", "r", stdin);
	//freopen("output.dat", "w", stdout);
	while(1){
		scanf("%s", buf);
		memset(&sta, 0, sizeof(struct state));
		if(0 == strcmp(buf, "0"))
			break;

		analyse(sta, buf);
		for(i=1; i<=12; i++){
			scanf("%s", buf);
			analyse(sta, buf);
		}
		func(sta);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值