扎金花

两个搜狐的程序员加了一个月班,终于放假了,于是他们决定扎金花渡过愉快的假期 。

游戏规则:
共52张普通牌,牌面为2,3,4,5,6,7,8,9,10,J,Q,K,A之一,大小递增,各四张; 每人抓三张牌。两人比较手中三张牌大小,大的人获胜。 

对于牌型的规则如下: 
1.三张牌一样即为豹子 
2.三张牌相连为顺子(A23不算顺子) 
3.有且仅有两张牌一样为对子 豹子>顺子>对子>普通牌型 在牌型一样时,比较牌型数值大小(如AAA>KKK,QAK>534,QQ2>10104) 在二人均无特殊牌型时,依次比较三张牌中最大的。大的人获胜,如果最大的牌一样,则比较第二大,以此类推(如37K>89Q) 如二人牌面相同,则为平局。 
解题思路:

首先拿到这两组牌后,将这两组牌进行转换,使每一张牌转化为对应的数值

2-2,3-3,4-4,5-5,6-6,7-7,8-8,9-9,10-10,J-11,Q-12,K-13,A-14

将两组牌转换以后,首先分别对他们排序

1)排序后,判断两组牌的类型。如果两组牌的类型不同,那就好办,只要按  豹子>顺子>对子>普通牌型 判断就可以

2)如果两组牌的类型相同,在进行具体的判断


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

//将str转化为对应一组的整数,如果str合法,返回true,否则返回false
bool strtoVec(string& str, vector<int> &vec)
{
	size_t i = 0;
	for(int cnt = 0; cnt < 3; cnt++)
	{ 
		switch(str[i]) {
		case '1':
				if(str[i+1] != '0')
				{
					return false;
				}
				vec.push_back(10);
				i = i + 2;
				break;
		case '2':;
		case '3':;
		case '4':;
		case '5':;
		case '6':;
		case '7':;
		case '8':;
		case '9':
			vec.push_back(str[i] - '2' + 2);
			i++;
			break;
		case 'J':
			vec.push_back(11);
			i++;
			break;
		case 'Q':
			vec.push_back(12);
			i++;
			break;
		case 'K':
			vec.push_back(13);
			i++;
			break;
		case 'A':
			vec.push_back(14);
			i++;
			break;
		default:
			return false;
		};
	}
	if(i != str.size())
	{
		return false;
	}
	return true;
}

//判断牌的类型:如果是豹子返回4,顺子返回3,对子返回2,其他返回1
int judgeCards(vector<int> &vec)
{
	if(vec[2] == vec[1] && vec[1] == vec[0])
		return 4;
	if(vec[0] + 1 == vec[1] && vec[1] + 1 == vec[2])
		return 3;
	if(vec[0] == vec[1] || vec[1] == vec[2])
		return 2;
	return 1;
}
//comp函数是在两组牌类型相同的情况下判断,两组牌的大小
//两组牌相等返回0, vec1大于vec2返回1, vec1小于vec2返回-1
int comp(vector<int> &vec1, vector<int> &vec2, int type1)
{
	switch(type1)
	{
	case 4://都为豹子
		if(vec1[0] == vec2[0]){
			return 0;
		}
		else if(vec1[0] > vec2[0]){
			return 1;
		}
		else {
			return -1;
		}
		break;
	case 3://都为顺子
		if(vec1[2] > vec2[2]){
			return 1;
		}
		else if(vec1[2] < vec2[2]){
			return -1;
		}
		else {//vec1[2] == vec2[2],且它们均为顺子
			return 0;
		}
		break;
	case 2://都为对子
		//由于我们的数组时经过排序的,所以对子的那个元素一定是中间位置上的那个元素
		if(vec1[1] == vec2[1])
			return 0;
		else if(vec1[1] > vec2[1])
			return 1;
		else
			return -1;
		break;
	case 1://都为普通牌
		for(int i = 2; i >= 0; i--)
		{
			if(vec1[i] == vec2[i])
				{continue;}
			else if(vec1[i] < vec2[i])
			{
				return -1;
			}
			else {
				return 1;
			}
		}
		return 0;
		break;
	}
}

int main(void)
{
	string str1, str2;
	vector<int> vec1(3, 0);
	vector<int> vec2(3, 0);
	bool b1, b2;
	while(cin >> str1 >> str2)
	{
		vec1.clear();
		vec2.clear();
		//将两组牌转化为对应的数字
		b1 = strtoVec(str1, vec1);
		b2 = strtoVec(str2, vec2);
		if(b1 && b2)
		{
			sort(vec1.begin(), vec1.end());
			sort(vec2.begin(), vec2.end());
			//判断两组牌的类型,并将他们的类型分别保存在type1/type2中
			int type1 = judgeCards(vec1);
			int type2 = judgeCards(vec2);
			if (type1 > type2)//两组牌属于不同类型
			{
				cout << 1 << endl;
			}
			else if(type1 < type2)//两组牌属于不同类型
			{
				cout << -1 << endl;
			}
			else if(type1 == type2)//如果两组牌属于同一类型
			{
				int result = comp(vec1, vec2, type1);
				switch(result) {
				case 0:
					cout << 0 << endl;
					break;
				case 1:
					cout << 1 << endl;
					break;
				default:
					cout << -1 << endl;
					break;
				}
			}
		}
		else{//输入不合法
			cout << -2 << endl;
		}
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值