1-7 德州扑克(c++)

题目:

最近,阿夸迷于德州扑克。所以她找到了很多人和她一起玩。由于人数众多,阿夸必须更改游戏规则:

所有扑克牌均只看数字,不计花色。
每张卡的值为1、2、3、4、5、6、7、8、9、10、11、12、13 中的一种(对应A,2、3、4、5、6、7, 8、9、10,J,Q,K)
每位玩家从一副完整的扑克牌(没有大小王)中抽出五张扑克牌,可能出现的手牌的值从低到高排列如下:

高牌:不包含以下牌的牌。对于都是高牌的牌,按照五张牌的值的和进行从大到小排序。
对子:手中的5张牌中有2张相同值的牌。对于都拥有对子的牌,按构成该对子的牌的值进行从大到小地排序。如果这些都相同,则按手牌中余下3张牌的值的和进行从大到小排序。
两对:手中拥有两对不同的对子。对于都包含两对的手牌,按其最高对子的值进行从大到小排序。如果最高对子相同,则按另一个对子的值从大到小地进行排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
三条:手中拥有3张相同值的牌。对于都包含三条的手牌按构成三条的牌的值进行从大到小地排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
满堂红:手中拥有一个三条和一个对子。同理,先按三条大小排序,如果三条大小相同,则按对子大小进行排序。
四条:手中拥有4张相同值的牌。对于都包含四条的手牌按构成四条的牌的值进行从大到小地排序。如果这些值相同,则按剩余牌的值从大到小地进行排序。
顺子:手中拥有5张连续值的卡。对于都包含顺子的手牌按顺子最大的牌进行排序。
皇家同花顺:手中拥有10到A(10、J、Q、K、A)。是最大的手牌!**

现在,阿夸已经知道了每个人的手牌,她想要知道所有人的排名列表。如果玩家的手牌大小相等,则按玩家名字的字典序输出。保证没有重复的名字。你能帮帮她吗?

输入格式:
第一行包含一个正整数 N (1<=N<=100000) ,表示玩家的人数。
接下来 N 行,每行包含两个字符串:m (1<=|m|<=10 ) ,表示玩家的名字;s (1<=|s|<=10),表示玩家的手牌。

输出格式:
输出 N个玩家的排名列表。

输入样例:
3
Alice AAA109
Bob 678910
Boa 678910

输出样例:
Boa
Bob
Alice

重点在如何分类

#include <iostream>
#include <algorithm>
using namespace std;
struct men
{
	string name;
	string pai;
	int flag;
	int sum,d,dd;
};
void set(struct men *pl){
	int h[14]={};//0==10
	pl->sum=0;pl->d=0;pl->dd=0;
	for(int i=0;i<pl->pai.length();i++)//将字母转换为数字
	{
		if(pl->pai[i]=='A'){
			pl->sum+=1;	h[1]++;
		}
		else if(pl->pai[i]=='J'){
			pl->sum+=11;h[11]++;		
		}
		else if(pl->pai[i]=='Q'){
			pl->sum+=12;h[12]++;			
		}
		else if(pl->pai[i]=='K'){
			pl->sum+=13;h[13]++;	
		}
		else
		{
			if(pl->pai[i]-'0'!=1)
			{
				h[pl->pai[i]-'0']++;
				pl->sum+=pl->pai[i]-'0';
			}
			else pl->sum+=10;
		}
	}
	h[10]=h[0];
	if(h[1]==1&&h[10]==1&&h[11]==1&&h[12]==1&&h[13]==1){
		pl->flag=8;
		return;//皇家顺子
	}
	int fl=1;
	for(int i=1;i<14;i++){
		if(h[i]==4||h[i]==5){//四条
			pl->flag=6;
			pl->sum-=i*4;
			pl->d=i;
			break;
		}
		if(h[i]==3){//三条
			pl->flag=4;
			pl->sum-=i*3;
			pl->d=i;
			for(int j=1;j<14;j++){
				if(h[j]==2){
					pl->flag=5;//满堂红
					pl->dd=j;
				}
			}
			break;
		}
		if(h[i]==2){//对子
			pl->flag=2;
			pl->sum-=i*2;
			pl->d=i;
				for(int j=i+1;j<14;j++){//有没有第二个对子?
				if(h[j]==2){
					pl->flag=3;
					pl->d=i>j?i:j;
					pl->dd=i<j?i:j;
					break;
				}
				if(h[j]==3){
				pl->flag=5;//满堂红
				pl->d=j;
				pl->dd=i;
				break;
			}
			}
			break;
		}
		if(fl==1&&h[i]==1){
			for(int j=i+1;j<i+5;j++){
				if(h[j]!=1)
				fl=0;
				}
				if(fl==1){
				pl->flag=7;
				pl->d=h[i];
				break;
				}
			}
		}
		
	}
bool cmp(struct men p1,struct men p2)
{//下面的10000、100...是用来分配权重的
		if((p2.flag-p1.flag)*10000+(p2.d-p1.d)*100+(p2.dd-p1.dd)>0)
			return 0;
		else if((p2.flag-p1.flag)*10000+(p2.d-p1.d)*100+(p2.dd-p1.dd)<0)
			return 1;
		else
		{
			if(p2.sum-p1.sum>0)
				return 0;
			else if(p2.sum-p1.sum<0)
				 return 1;
			else{
				if(p2.name>p1.name)
					return 1;
				else return 0;			
			}
		}
}
int main()
{
	int n,i;
	cin>>n;
	struct men *pll=new struct men[n];
	for(i=0;i<n;i++)
	{
		cin>>pll[i].name>>pll[i].pai;
		set(&pll[i]);
	}
	sort(pll,pll+n,cmp);
	for(int i=0;i<n;i++)
		cout<<pll[i].name<<endl;
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值