Wek9 B - Brand type judgment

问题描述:

最近,东东沉迷于打牌。所以他找到 HRZ、ZJM 等人和他一起打牌。由于人数众多,东东稍微修改了亿下游戏规则:
所有扑克牌只按数字来算大小,忽略花色。
每张扑克牌的大小由一个值表示。A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K 分别指代 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13。
每个玩家抽得 5 张扑克牌,组成一手牌!(每种扑克牌的张数是无限的,你不用担心,东东家里有无数副扑克牌)
理所当然地,一手牌是有不同类型,并且有大小之分的。
举个栗子,现在东东的 “一手牌”(记为 α),瑞神的 “一手牌”(记为 β),要么 α > β,要么 α < β,要么 α = β。
那么这两个 “一手牌”,如何进行比较大小呢?首先对于不同类型的一手牌,其值的大小即下面的标号;对于同类型的一手牌,根据组成这手牌的 5 张牌不同,其值不同。下面依次列举了这手牌的形成规则:
大牌:这手牌不符合下面任一个形成规则。如果 α 和 β 都是大牌,那么定义它们的大小为组成这手牌的 5 张牌的大小总和。
对子:5 张牌中有 2 张牌的值相等。如果 α 和 β 都是对子,比较这个 “对子” 的大小,如果 α 和 β 的 “对子” 大小相等,那么比较剩下 3 张牌的总和。
两对:5 张牌中有两个不同的对子。如果 α 和 β 都是两对,先比较双方较大的那个对子,如果相等,再比较双方较小的那个对子,如果还相等,只能比较 5 张牌中的最后那张牌组不成对子的牌。
三个:5 张牌中有 3 张牌的值相等。如果 α 和 β 都是 “三个”,比较这个 “三个” 的大小,如果 α 和 β 的 “三个” 大小相等,那么比较剩下 2 张牌的总和。
三带二:5 张牌中有 3 张牌的值相等,另外 2 张牌值也相等。如果 α 和 β 都是 “三带二”,先比较它们的 “三个” 的大小,如果相等,再比较 “对子” 的大小。
炸弹:5 张牌中有 4 张牌的值相等。如果 α 和 β 都是 “炸弹”,比较 “炸弹” 的大小,如果相等,比较剩下那张牌的大小。
顺子:5 张牌中形成 x, x+1, x+2, x+3, x+4。如果 α 和 β 都是 “顺子”,直接比较两个顺子的最大值。
龙顺:5 张牌分别为 10、J、Q、K、A。
作为一个称职的魔法师,东东得知了全场人手里 5 张牌的情况。他现在要输出一个排行榜。排行榜按照选手们的 “一手牌” 大小进行排序,如果两个选手的牌相等,那么人名字典序小的排在前面。
不料,此时一束宇宙射线扫过,为了躲避宇宙射线,东东慌乱中清空了他脑中的 Cache。请你告诉东东,全场人的排名

Input:
输入包含多组数据。每组输入开头一个整数 n (1 <= n <= 1e5),表明全场共多少人。
随后是 n 行,每行一个字符串 s1 和 s2 (1 <= |s1|,|s2| <= 10), s1 是对应人的名字,s2 是他手里的牌情况。

Output:
对于每组测试数据,输出 n 行,即这次全场人的排名。

Sample Input:
3
DongDong AAA109
ZJM 678910
Hrz 678910

Sample Output:
Hrz
ZJM
DongDong

解题思路:

这道题前面已经做过类似的且难度更高的,我的思路就是创建一个结构体,数据成员有牌手名,字符串描述的牌pai,Ptype描述了牌型,card描述了14张牌的拥有情况。定义了一个全局函数:clac_type函数,这个函数实现也不难,就是对字符串pai判断牌号,遍历这个字符串,记录到card数组里,表示每张牌的拥有情况,接下来就是判断牌型,这里还定义了一个变量differ,这个变量表明了五张牌中有几张不同的,若是有五个,说明这个牌牌型只能是大牌、顺子和龙顺,龙顺直接判断五张牌是否符号条件即可,顺子的话只要有一张牌为1了(即card[i],后面的四张牌也必须全是1,否则不是退出判断,该牌为大牌。如果differ不为1,就有一个循环,遍历card数组,记录牌数为1的有几个,牌数为i的有几个,方便后面直接进行牌型判断。如:炸弹就是cnt[4]=1=或者cnt[5]==1,其他类似判断即可。
最后就是结构体中比较函数的设计部分,这个部分逻辑比较简单,最后对player数组排序输出牌手名即可。

实验代码:

#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
string paihao=".A23456789.JQK";
int cfind(char s)		//查找牌号 
{
	for(int i=1;i<14;i++)
		if(s==paihao[i])
			return i;
}
int n;
struct player
{
	//数据成员 
	string name;
	string pai;
	int Ptype;
	int card[14];
	//比较函数 
	bool operator<(const player& p) const		 
	{
		if(Ptype!=p.Ptype)
			return  Ptype>p.Ptype;
		if(Ptype==1) 		
		{
			int sum1=0,sum2=0;
			for(int i=1;i<14;i++)
				if(card[i]==1)
					sum1+=i;			
			for(int i=1;i<14;i++)
				if(p.card[i]==1)
					sum2+=i;	
			if(sum1!=sum2)
				return sum1>sum2;
			return name<p.name;
		} 
		if(Ptype==2)		
		{
			int sum1=0,Psum1=0,num2,Pnum2;
			for(int i=1;i<14;i++)	
			{	
				if(card[i]==0)	continue;
				if(card[i]==1)	sum1+=i;
				else num2=i;		 	
			}
			for(int i=1;i<14;i++)		
			{	
				if(p.card[i]==0)	continue;
				if(p.card[i]==1)	Psum1+=i;
				else Pnum2=i;			
			}
			if(num2!=Pnum2)	return num2>Pnum2;
			if(sum1!=Psum1)	return sum1>Psum1;
			return name<p.name;
		}
		if(Ptype==3)		//两对 
		{
			int num1,Pnum1,num2[2],num2_index=0,Pnum2[2],Pnum2_index=0;
			for(int i=1;i<14;i++)	
			{
				if(card[i]==0)	continue;
				if(card[i]==2)	num2[num2_index++]=i;
				else num1=i;
			}
			for(int i=1;i<14;i++)	
			{
				if(p.card[i]==0)	continue;
				if(p.card[i]==2)	Pnum2[Pnum2_index++]=i;
				else Pnum1=i;
			}
			if(num2[1]!=Pnum2[1])	return num2[1]>Pnum2[1];	
			if(num2[0]!=Pnum2[0])	return num2[0]>Pnum2[0];
			if(num1!=Pnum1)	return num1>Pnum1;
			return name<p.name; 
		}
		if(Ptype==4)	//三个 
		{
			int num3,Pnum3,sum1=0,Psum1=0;	
			for(int i=1;i<14;i++)
			{
				if(card[i]==0)	continue;
				if(card[i]==1)	sum1+=i;
				else num3=i;
			}
			for(int i=1;i<14;i++)
			{
				if(p.card[i]==0)	continue;
				if(p.card[i]==1)	Psum1+=i;
				else Pnum3=i;
			}
			if(num3!=Pnum3)	return num3>Pnum3;
			if(sum1!=Psum1) return sum1>Psum1;
			return name<p.name;
		}
		if(Ptype==5)		//三带二
		{
			int num2,Pnum2,num3,Pnum3;		
			for(int i=1;i<14;i++)
			{
				if(card[i]==0)	continue;
				if(card[i]==2)	num2=i;
				if(card[i]==3)	num3=i;
			}
			for(int i=1;i<14;i++)
			{
				if(p.card[i]==0)	continue;
				if(p.card[i]==2)	Pnum2=i;
				if(p.card[i]==3)	Pnum3=i;
			}
			if(num3!=Pnum3)	return num3>Pnum3;
			if(num2!=Pnum2)	return num2>Pnum2;
			return name<p.name;
		} 
		if(Ptype==6)		//四带一 
		{
			int num4,num1,Pnum4,Pnum1;
			for(int i=1;i<14;i++)
			{
				if(card[i]==0)	continue;
				if(card[i]==4)	num4=i;
				else if(card[i]==1)	num1=i;
				else if(card[i]==5)			
				{
					num4=i,num1=i;
					break;
				}
			}
			for(int i=1;i<14;i++)
			{
				if(p.card[i]==0)	continue;
				if(p.card[i]==4)	Pnum4=i;
				else if(p.card[i]==1)	Pnum1=i;
				else if(p.card[i]==5)			
				{
					Pnum4=Pnum1=i;
					break;
				}
			}
			if(num4!=Pnum4)	return num4>Pnum4;
			if(num1!=Pnum1)	return num1>Pnum1;
			return name<p.name;
		}
		if(Ptype==7)	
		{
			int start,Pstart;
			for(int i=1;i<14;i++)
				if(card[i]==1)
				{
					start=i;
					break;
				}
			for(int i=1;i<14;i++)
				if(p.card[i]==1)
				{
					Pstart=i;
					break;
				}
			if(start!=Pstart)	return start>Pstart;
			return name<p.name;
		} 
		if(Ptype==8)
			return name<p.name;
	}
};
int cnt[6];					
const int inf=1e5+10;
player play[inf];			//存储玩家 
void clac_type(player& p)	
{
	string s=p.pai;
	int len=s.length();
	for(int i=1;i<14;i++)
		p.card[i]=0;		 
	int differ=0,phao;		
	
	for(int i=0;i<6;i++)
		cnt[i]=0;
	for(int i=0;i<len;i++)
	{
		if(s[i]!='1')		
		{
			phao=cfind(s[i]);
			if(p.card[phao]==0)	differ++;		
			p.card[phao]++;
		}
		else 		//如果是1
		{ 
			if(p.card[10]==0)	differ++;
			p.card[10]++;
			i++;		
		} 
	}	
	if(differ==5)		
	{ 
		if(p.card[1]==1&&p.card[10]==1&&p.card[11]==1&&p.card[12]==1&&p.card[13]==1) 
		{
			p.Ptype=8;
			return;		
		}	 
		for(int i=1;i<14;i++)
		{
			if(p.card[i]==1)		
			{
				for(int j=i+1;j<i+5;j++)
					if(p.card[j]!=1)	
					{
						p.Ptype=1;
						return;		
					}
				p.Ptype=7;			
				return; 
			}
		}
	} 
	for(int i=1;i<14;i++)			
		cnt[p.card[i]]++;
	//如果是炸弹	
	if(cnt[4]==1||cnt[5]==1)		//炸弹 
	{
		p.Ptype=6;
		return;
	}
	if(cnt[3]==1&&cnt[2]==1)		//三带二 
	{
		p.Ptype=5;
		return;
	}
	if(cnt[3]==1&&cnt[1]==2)		
	{
		p.Ptype=4;
		return; 
	}
	if(cnt[2]==2)						//两对 
	{
		p.Ptype=3;
		return;
	}
	if(cnt[1]==3)						//一对
	{
		p.Ptype=2;
		return;
	}
}
void getAns()
{
	for(int i=0;i<n;i++)		
		clac_type(play[i]);
	sort(play,play+n);			//排序 
	for(int i=0;i<n;i++)
		cout<<play[i].name<<endl;
}
int main(void)
{
	while(cin>>n)
	{
		for(int i=0;i<n;i++)
			cin>>play[i].name>>play[i].pai;
		getAns();
	}
	return 0; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值