其他分享
首页 > 其他分享> > PTA德州扑克

PTA德州扑克

作者:互联网

德州扑克

题目描述

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

所有扑克牌均只看数字,不计花色。
每张牌的值为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<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
typedef struct{
	char name[15];
	int order;
	int sum;
}player;
vector <player > players;
int judge_duizi(int a[])
{
     int duizi=0; 
     int cnt_5[14];
     memset(cnt_5,0,sizeof(cnt_5));
     for(register int i=0;i<=4;i++)
     {
         cnt_5[a[i]]++;
	 }
	 for(register int i=13;i>=1;i--)//倒序的话,是因为为了先抓到尽可能大的数 (用于双对子间的比较) 
     {
         if(cnt_5[i]==2)
         {
         	duizi=duizi*14+i;//这里有一个针对双对子放大的处理 
		 }
	 }
     return duizi;
}
int judge_santiao(int a[])
{
for(register int i=0;i<=2;i++)
   {    
        int flag=1;
   		for(register int j=i;j<=i+1;j++)
    	{
	       
	    	if(a[j]!=a[j+1])   //1  0
	    	{
			flag=0;
	    	}
	    
	    }	
		if(flag)
	       return a[2];	  
    }	
    return 0;
}
int judge_sitiao(int a[])
{
   for(register int i=0;i<=1;i++)
   {
        int flag=a[(1-i)*4]; //0  4//1  0  //这个地方比较骚,只是用来去不同于四条的那个数,当然如果是五条也没事 
   		for(register int j=i;j<=i+2;j++)
    	{
	    	if(a[j]!=a[j+1])   
	    	{
			flag=0;//不是4条 
	    	}
	    		  
	    }if(flag!=0)//是4条的话,flag大于0 
		       return a[1]*4*14+flag;//排序过,a[1]必然属于四条 
    }	
    return 0;
}
int judge_shunzi(int a[])
{
	for(register int i=1;i<=4;i++)
	{
		if(a[i]-a[i-1]!=1)
		  return 0;
	}
	return 1;
}
void judge(int a[],int *order,int *ju1)
{
    if(a[0]==1&&a[1]==10&&a[2]==11&&a[3]==12&&a[4]==13)
    {
    	*order=7;// 优先级为7; 
    	*ju1=0;
	}
	else
	if(judge_shunzi(a))
	{
		*order=6;// 优先级为6;
		*ju1=a[4];
	}
	else
	{
		int k=judge_sitiao(a);
    	if(k>0)
    	{
 	    	*order=5;// 优先级为5;
 	    	*ju1=k;
    	}
		else
		{
			int duizi=judge_duizi(a);//返回的是特殊的对数,双对大于15,单对大于0,没对等于0 
			int santiao=judge_santiao(a);//返回的是重复的数字 
			if(duizi>0&&santiao>0)//由于三条的存在,必然不可能出现双对,故不需考虑duizi<14 
			{
				*order=4;// 优先级为4;
				 
				*ju1=duizi+santiao*100;
			//	cout<<duizi/2<<"   "<<santiao<<endl;
			}
			else
			if(santiao>0)//三条 
			{
				*order=3;// 优先级为3;
				int subsum=0;
				for(register int i=4;i>=0;i--)
				{
					if(a[i]!=santiao)
					{
						subsum=subsum+a[i];
						//cout<<subsum<<endl; 
					}
				}
			    *ju1=santiao*100+subsum;
			}
			else
			if(duizi>14) //双对,用14来分割单对和双对 
			{
				*order=2;// 优先级为2;
				int cnt_13[14];
				memset(cnt_13,0,sizeof(cnt_13));
				int alone;
				for(register int i=0;i<5;i++)
				{
					cnt_13[a[i]]++;
				}
				for(register int i=1;i<=13;i++)
				{
					if(cnt_13[i]==1)
					{
						alone=i;	//找到落单的一员 
					}
				}
				//cout<<alone<<endl;
		    	*ju1=duizi*100+alone;//100只是起放大的作用,并不是很严格 
			}
			else
			if(duizi>0)
			{
				*order=1;// 优先级为1;
				int subsum=0;
				int re=duizi;
				for(register int i=4;i>=0;i--)
				{
					if(a[i]!=re)
					{
						subsum+=a[i];
					}
				}
				*ju1=duizi*100+subsum;
			}
                        else
                        {
                	  int sum=0;
            	          for(register int i=0;i<=4;i++)
            	               sum+=a[i];
                	  *order=0;
			  *ju1=sum;   
		        }
	      }
	}
}


bool cmp_player(player a,player b)
{
	if(a.order==7&&b.order==7)
	{
		if(strcmp(a.name,b.name)<0)return 1;
		else return 0;
	}
	if(a.order==b.order)
	{
		if(a.sum==b.sum)
		   if(strcmp(a.name,b.name)<0)return 1;
	    	else return 0;
		else
		return a.sum>b.sum;
	}
	else return a.order>b.order;
}
int main()
{
	int n;
	cin>>n;
	char p_name[15];
	string p_cards;
	for(register int i=1;i<=n;i++)
	{
		cin>>p_name>>p_cards;
		player new_player;
		int p[5];
		int pos=0,order=0,ju1=0;
		//转换数值 
		for(register int j=0;j<p_cards.length();j++)
		{
            if(p_cards[j]=='A')
                p[pos]=1;
            else 
            if(p_cards[j]=='J')
                p[pos]=11;
            else 
            if(p_cards[j]=='Q')
                p[pos]=12;
            else 
            if(p_cards[j]=='K')
                p[pos]=13;
            else 
	        if(p_cards[j]=='1')
		   	{
			 	p[pos]=10;
			 	j++;
			}  
			else
			{
		  		p[pos]=p_cards[j]-'0';
		    } 
			 pos++;			
		}
		sort(p,p+5);//排序 
		judge(p,&order,&ju1);
		strcpy(new_player.name,p_name);
		new_player.order=order;
		new_player.sum=ju1;
		players.push_back(new_player);
	}
	sort(players.begin(),players.end(),cmp_player);
	for(register int i=0;i<n;i++)
	{
		cout<<players[i].name<<endl;
	}
	return 0;
}

感谢

感谢lygg的指导

标签:int,register,PTA,手牌,对子,duizi,德州,扑克,排序
来源: https://www.cnblogs.com/BeautifulWater/p/14487976.html