德州扑克
题目描述
德州扑克 (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的指导