2012 华为编程大赛 成都地区

扑克牌比较(30分)

问题描述:

在扑克中,牌的类型包括:A(1),2,3,4,5,6,7,8,9,T(10),J(11),Q(12),K(13),D(小鬼devilkin),B(大鬼Belial)。

请做一个简单的程序,输入两张牌的字符,比如"2"和"K",判断牌的大小,规则如下:

B>D>2>A>K>Q>J>10....>3 最小的为3

判断规则:比较cFirstCard和cSecondCard,如果FirstCar大,那么返回1;如果相同,返回0;如果FirstCar小,返回-1。

要求实现函数:

int CompareOneCard(char cFirstCard, char cSecondCard)


【输入】 char cFirstCard:需要比较的第一张牌

char cSecondCard: 需要比较的第二张牌

注意:输入的为字符’A’,’2’,…,’9’,’T’,’J’,’Q’,’K’,’D’,’B’

【返回】  int类型:返回两张牌的比较结果

注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌均为字符’1’,’2’…’9’,大写的’A’,’T’,’J’,’Q’,’K’,’D’,’B’。

举例:  

输入:’4’、’5’,返回:-1

输入:’6’、’6’,返回:0


2. 干瞪眼(30分)

问题描述:

在成都,流行一种扑克游戏叫“干瞪眼”。使用扑克牌,包括:A(1),2,3,4,5,6,7,8,9,T(10),J(11),Q(12),K(13)。

注意:10用T替换,这里暂时不考虑大鬼和小鬼。

两手牌的大小规则如下:

a)    单牌:4比3大,5比4大,只有两张牌刚好大一点时才能进行比较,比较顺序为:A>K>Q>J>T>9>8>7>6>5>4>3。

比如:6大于5,但是不能比4大,6和4不能比较。单牌2属于特殊牌,他可以和其他所有普通单牌比较,并且是最大的。

请注意3,他不能大于任何牌。

b)    对子:即两张牌的点数相同,规则和单牌相似,也需要进行类似处理。两个2是特殊对子,可以大于所有的其他对子。

注意:对子和单牌是不能进行比较的。

c)    炸弹:3个点数相同的牌。炸弹可以大于任何单张和对子,炸弹之间的比较不用像单牌和对子那样,只能大一点才能比较。

只要满足:222>AAA>KKK>QQQ>JJJ>TTT>…>333的规则的即可。即222是最大的,AAA可以大于KKK,也可以大于333。

d)    其他规则暂不考虑实现

现在请你实现一个程序,自动判断两手牌的大小,注意:输入的牌只会出现3种类型:单张,对子,炸弹。张数最多3张。

不会出现2个单牌。比如”25”,也不会出现一个对子加单牌,比如”334”等,类似输入异常你可以不用考虑。

但是pFirstCards为单牌,pSecondCards为对子,类似的组合输入是合法的。

要求实现函数:

int CompareCards(char *pFirstCards, char *pSecondCards)

【输入】  char *pFirstCards:需要比较的第一手牌

char *pSecondCards:需要比较的第二手牌

【返回】  int 类型,返回值说明:
如果pFirstCards和 pSecondCards无法比较,比如”3”和”6”;”55”和”6”等,返回0。
如果pFirstCards大于pSecondCards,返回1。
如果pFirstCards等于 pSecondCards,返回2。
如果pFirstCards小于 pSecondCards,返回3。

注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌均为字符’1’,’2’..’9’,大写的’A’,’T’,’J’,’Q’,’K’。

示例

输入: “77”、 “33”,返回:0
输入: “77”、 “77”,返回:2

3. 麻将胡牌(40分)

问题描述:

说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
现实生活如此,网络上各种各样的麻将游戏也非常的多,现在游戏公司H正在做一款麻将游戏,
其中判断是否胡牌的部分希望由你来做。
成都麻将规则如下:
麻将只能包括3种类型:条,筒,万。没有“门、东南西北、红中”。每种牌都是数字从1到9,每个数字有4张,共36张,筒,万,条均一样。
胡牌规则如下:
a) 手里面的牌最多只有两种类型,即必须打缺一种,不能出现:条,筒,万都存在的情况。
b)  必须有一个对子,即两张相同的牌,比如:两个2筒,两个4条等。
c)  剩余的牌,每3张需要凑成一个有效牌,比如:3个一样的牌(3个2筒),或者3个顺子(1条2条3条),
如果所有的牌都能够凑好,再满足规则b和a,有一个对子,并且所有的牌只有两种,那么就可以胡牌了。
d)  有一种特殊牌,叫做七对,即全部的牌都是成对出现,比如:2筒2筒5筒5筒3筒3筒4条4条8条8条1条1条2条2条,
一共7对,再满足条件a,也可以胡牌。
e)  假设牌不会出现碰的情况,即手里面的牌肯定是14张。输入数据肯定都是麻将牌,不用考虑异常输入。
也不用考虑会输入“门”,“红中”等成都麻将中不会出现的牌。

要求实现函数:

bool IsMahjonggWin(char *pCards)

【输入】  char *pCards:参数说明:

假设:
条子为:T,2条输入为:2T
筒子为:D,3筒输入为:3D
万子为:W,4万输入为:4W
pCards:输入麻将序列。比如:”1T2T2T2T3T7T8T9T5D4D7D8D8D8D”

【返回】 bool类型:如果能够胡牌,返回true;如果不能胡牌,返回false。

比如:“7T1T8T2T2T2T3T9T5D4D3D8D8D8D”可以转换成“1T2T3T2T2T7T8T9T3D4D5D8D8D8D”,可以胡牌。

注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌为字符串,字母为大写的”TDW”,请编码的时候注意。

示例

输入: “1D2D2D2D3D3D4D4D5D5D5D6D6D7D”,返回:true
输入: “1D1D1D3D3D3D5D5D5D7D7D7D2W3W”,返回false


//第一题
#include<stdio.h>
#include<malloc.h>
int CompareOneCard(char cFirstCard, char cSecondCard);
int main()
{
	int n;
	int ch1, ch2;
	printf("数入测试数据的组数\n");
	scanf("%d", &n);
	getchar();
	while(n--)
	{
		printf("输入数据\n");
		scanf("%c %c", &ch1, &ch2);
		getchar();
		printf("%d\n", CompareOneCard(ch1, ch2));

	}
}

int CompareOneCard(char ch1, char ch2)
{
	char temp[2];
	int i = 0;
	temp[0] = ch1;
	temp[1] = ch2;
	for(i = 0; i < 1; ++i)
	{
		switch(temp[i])
		{
			case 'T': temp[i] = '9'+1;break;
			case 'J': temp[i] = '9'+2;break;
			case 'Q': temp[i] = '9' + 3;break;
			case 'K': temp[i] = '9' + 4;break;
			case 'A': temp[i] = '9' + 5;break;
			case '2': temp[i] = '9' + 6;break;
			case 'D': temp[i] = '9' + 7;break;
			case 'B': temp[i] = '9' + 8;break;
			default: break;
		}
	}
	if(temp[0] > temp[1])
		return 1;
	else if(temp[0] == temp[1])
		return 0;
	else 
		return -1;
}


//第二题
#include<stdio.h>
#include<string.h>
#include<math.h>
int CompareCards(char *pFirstCards, char *pSecondCards);
int main()
{
	char str1[100];
	char str2[100];
	int n;
	int Result = 0;
	printf("输入测试的组数\n");
	scanf("%d", &n);
	getchar();
	while(n--)
	{
		printf("输入测试数据\n");
		gets(str1);
		gets(str2);
		Result = CompareCards(str1, str2);
		printf("%d\n", Result);
	}
}
int CompareCards(char *pFirstCards, char *pSecondCards)
{
	void Traves(char *str);
	void Compare(int *, char *, char *);
	int len1 = strlen(pFirstCards);
	int len2 = strlen(pSecondCards);
	int result;
	Traves(pFirstCards);
	Traves(pSecondCards);
	 result = 0;
	if(len1 == len2)
	{
		switch(len1)
		{
		case 1:
			Compare(&result, pFirstCards, pSecondCards);
			break;
		case 2:
			Compare(&result, pFirstCards, pSecondCards);
			break;
		case 3:
			if(*pFirstCards == *pSecondCards)
				result = 2;
			else
				result = ((*pFirstCards > *pSecondCards) ? 1 : 3);
			break;
		default:
			break;
		}
	}
	else
	{
		switch(len1)
		{
		case 1: result = ((len2 == 2) ? 0 : 3); break;
		case 2: result = ((len2 == 1) ? 0 : 3); break;
		case 3: result = 1;break;
		default:
			break;
		}
	}
	return result;
}

void Traves(char *str)//按照牌的大小顺序转换输入的数据
{
	while(*str != '\0')
	{
		switch(*str)
		{
			case 'T': *str = '9'+1;break;
			case 'J': *str = '9'+2;break;
			case 'Q': *str = '9' + 3;break;
			case 'K': *str = '9' + 4;break;
			case 'A': *str = '9' + 5;break;
			case '2': *str = '9' + 6;break;
			default: break;
		}
		str++;
	}
}

void Compare(int *result, char *pFirstCards, char *pSecondCards)
{
	if(*pFirstCards == *pSecondCards)
		*result = 2;
	else
	{
		if(*pFirstCards == '9'+6 || *pSecondCards == '9'+6)
			*result = ((*pFirstCards == '9'+6) ? 1 : 3);
		else if(fabs(*pFirstCards - *pSecondCards) == 1)
			*result = (*pFirstCards > *pSecondCards) ? 1 : 3;
		else
			*result = 0;
	}
}


//第三题
#include<stdio.h>
int IsMahjonggWin(char *pCards);
int main()
{
	char str[100];
	int i;
	int n;
	printf("输入测试的组数\n");
	scanf("%d", &n);
	getchar();
	while(n--)
	{
		printf("输入一组测试数据\n");
		gets(str);
	    i = IsMahjonggWin(str);
		printf("%d\n", i);
	}
}
int IsMahjonggWin(char *pCards)
{
	int Check(int *, int);
	int T[10] = {0};
	int D[10] = {0};
	int W[10] = {0};
	char *First, *Second;
	int i = 0;
	int Two = 0;
	First = pCards;
	Second = pCards+1;
	while(*First != '\0')
	{
		switch(*Second)
		{
		case 'T': T[*First - '0']++; T[0]++;break;//T[0]存储条子的总张数,和每张牌的数字
		case 'D': D[*First - '0']++; D[0]++;break;
		case 'W': W[*First - '0']++; W[0]++;break;
		}
		First += 2;
		Second +=2;
	}
	if(T[0] > 0 && D[0] > 0 && W[0] > 0)
		return 0;
	else
	{
		for(i = 1; i < 10; ++i)
		{
			if(T[i]%4 == 0 || D[i] % 4 == 0 || W[i]%4 == 0)
				Two += 2;
			if(T[i] % 2 == 0 || D[i] % 2 == 0 || W[i] % 2 == 0)
				Two += 1;
		}
		if(Two == 7)//是否七对
			return 1;
		if(Check(T, T[0]) && Check(D, D[0]) && Check(W, W[0]))
			return 1;
		else 
			return 0;
	}
}

int Check(int *T, int n)
{
	int pos = 1;
	if(n == 0) //递归结束,
		return 1;
	while(pos <10 && !T[pos])
		pos++;
	if(pos == 10)
		return 1;
	if(n%3 == 2 && T[pos] >= 2)//是否测试过对子的情况
	{
		T[pos]-= 2;
		if(Check(T, n-2))
			return 1;
		T[pos] += 2;
	}

	if(T[pos] >= 3)//三个
	{
		T[pos] -= 3;
		if(Check(T, n-3))
			return 1;
		T[pos] += 3;
	}

	if(T[pos] >= 1 && T[pos+1] >= 1 && T[pos+2] >= 1)//顺子
	{
		T[pos]--;
		T[pos+1]--;
		T[pos+2]--;
		if(Check(T, n-3))
			return 1;
		T[pos]++;
		T[pos+1]++;
		T[pos+2]++;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值