Time limit | 1000 ms |
---|---|
Memory limit | 262144K |
Recently, Yang was addicted to Texas hold’em Poker. So he found a lot of people to play with him. Due to the large number of people, Yang had to change the rules of the game:
All poker cards are counted by number without suit.
Each card has a value which is one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 (denoted A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K)
Each player drew five poker cards from a complete deck of poker (without jokers), and the possible hand values are ranked as follows from lowest to highest:
High Card. Hands which do not fit any higher category are ranked by the sum of all the cards.
Pair. 2 of the 5 cards in the hand have the same value. Hands which both contain a pair are ranked by the value of the cards forming the pair. If these values are the same, the hands are ranked by the sum of the rest cards.
Two Pairs. The hand contains 2 different pairs. Hands which both contain 2 pairs are ranked by the value of their highest pair. Hands with the same highest pair are ranked by the value of their other pair. If these values are the same the hands are ranked by the value of the remaining card.
Three of a Kind. Three of the cards in the hand have the same value. Hands which both contain three of a kind are ranked by the value of the 3 cards. Hands with the same 3 cards are ranked by the sum of the rest two cards.
Full House. 3 cards of the same value, with the remaining 2 cards forming a pair. Ranked by the value of the 3 cards. Hands with the same 3 cards are ranked by the value of the cards forming the pair.
Four of a kind. 4 cards with the same value. Ranked by the value of the 4 cards. Hands with the same 4 cards are ranked by the remaining card.
Straight. Hand contains 5 cards with consecutive values. Hands which both contain a straight are ranked by their highest card.
Royal Straight. Straight from 10 to A (10-J-Q-K-A). The largest hand!
Now, Yang has known everyone’s cards, he wants a ranking list of all poker hands. If the value of players are equal, output their names in lexicographical order. It’s guaranteed that no one’s name repeats. Can you just help him?
Input
The input consists of multiple test cases, Each test case starts with a number n
(
1
≤
n
≤
1
0
5
,
1
≤
n
≤
1
0
5
)
(1 \le n \le 10^5,1≤n≤10 ^ 5 )
(1≤n≤105,1≤n≤105) represents the number of players, Then followed nn lines with each line two string m
(
1
≤
∣
m
∣
≤
10
,
1
≤
∣
m
∣
≤
10
)
(1 \le |m| \le 10,1≤∣m∣≤10)
(1≤∣m∣≤10,1≤∣m∣≤10) – the name of the player s
(
1
≤
∣
s
∣
≤
10
,
1
≤
∣
s
∣
≤
10
)
(1 \le |s| \le 10,1≤∣s∣≤10)
(1≤∣s∣≤10,1≤∣s∣≤10) the poker cards of the player.
Output
For each test case, you should output nn lines represent the ranking list.
Sample Input
3
Alice AAA109
Bob 678910
Boa 678910
Sample Output
Boa
Bob
Alice
题意就是根据卡牌的不同搭配赋以不同的值,输出值的排名。如果玩家的值相等,则按字典顺序输出其名称,保证没有人重复名字
可能的手牌值从高到低排列如下
皇家顺子:直接从10到A
顺子:一手牌包含5张连续值的卡,两个都包含顺子的牌按其最高牌排名
四张:4张相同价值的卡,按4张卡的价值排名,拥有相同4张牌的手按剩余卡牌排名
满牌:3张相同价值的卡,其余2张卡组成一对,按3张卡的价值排名,拥有相同3张牌的手按构成该对的牌的值排名
三张:手中的三张卡具有相同的值,双手都包含三种的手牌按3张牌的价值排名,拥有相同3张牌的手按其余两张牌的总和排名
两对:手里有2对不同的对,都有2对的手牌按其最高对的值排序,最高对的手牌相同按另一对的值排名。如果这些值相同,则按剩余卡的值进行排名
对:手中的5张卡中有2张具有相同的值。都包含一对的手按构成该对的牌的值进行排名。如果这些值相同,则手牌按其余牌的总和排名
卡牌:不适合任何较高级别的牌将按所有牌的总和排名
写了个好复杂的模拟emmm,因为卡牌值最多比三次,比如两对的时候先按两对的大值比较,再比另一对最后比剩余卡。所以最重要的是大档次,用第几档乘以1000000表示,后面依次下去
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{
char name[15];
int value;
}number[100005];
bool compare(node a, node b) {
if(a.value == b.value) return strcmp(a.name, b.name) < 0;
//值相等按名字字典序排名
return a.value > b.value;
}
int main(int argc, char const *argv[]) {
int n;
char c;
int card[13];
while(~scanf("%d", &n)) {
for (int i = 0; i < n; i++) {
scanf("%s", number[i].name);
memset(card, 0, sizeof(card));
for (int j = 0; j < 5; j++) {
scanf(" %c", &c);
switch (c) {
case 'A': card[0]++; break;
case '1': card[9]++; scanf("%c", &c); break;
//因为卡牌没有1所以一定是卡牌10
case 'J': card[10]++; break;
case 'Q': card[11]++; break;
case 'K': card[12]++; break;
default : card[c-'1']++;
}
//存手牌
}
for (int j = 0; j < 13; j++) {
if(card[j] >= 2) {
if (card[j] == 4) {
number[i].value += 6*1000000 + j*10000;//四张的卡牌值
}
else {
if (card[j] == 3) {
if(number[i].value / 1000000) number[i].value = 5*1000000 + j*10000 + ((number[i].value/10000-(number[i].value/1000000)*100))*100;//如果前面有对子,也就是说是满牌,第五档值加上之前第二档的降值
else number[i].value += 4*1000000 + j*10000;//不是满牌,按三张算
}
else {//有对子
if(number[i].value / 1000000) {//之前有对子或三张
if(number[i].value / 1000000 == 4) number[i].value += 1000000 + j*100;//之前是三张,从第四档变成第五档,加上对子的值
else {//之前是对子
int temp = number[i].value/10000-(number[i].value/1000000)*100;
number[i].value += 1000000 + (j-temp)*10000 + temp*100;
}
}
else number[i].value += 2*1000000 + j*10000;//只有对子
}
}
}
else if(card[j]) number[i].value += j;//加上单张的价值
}
if (number[i].value / 100 == 0) {//没有两张以上相同的牌,判断是否顺子
if (card[0]+card[9]+card[10]+card[11]+card[12] == 5) {
number[i].value = 8*1000000;//皇家顺子
continue;
}
for (int h = 0; h < 9; h++) {
if (card[h]+card[h+1]+card[h+2]+card[h+3]+card[h+4]==5) {
number[i].value = 7*1000000 + (h+4)*10000;//顺子
break;
}
}
}
}
sort(number, number+n, compare);//按值和字典序排序
for (int i = 0; i < n; i++) {
printf("%s\n", number[i].name);
}
}
return 0;
}