- 17.16%
- 1000ms
- 262144K
Texas hold'em Poker
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≤1051 \le n \le 10^51≤n≤105) represents the number of players, Then followed nnn lines with each line two string m (1≤∣m∣≤101 \le |m| \le 101≤∣m∣≤10) -- the name of the player s (1≤∣s∣≤101 \le |s| \le 101≤∣s∣≤10) the poker cards of the player.
Output
For each test case, you should output nnn lines represent the ranking list.
样例输入 复制
3 Alice AAA109 Bob 678910 Boa 678910
样例输出 复制
Boa Bob Alice
下午写的代码跟脑子进水了一样,太粗心了 找bug找了一小时。。。
AC Code:
#include <bits/stdc++.h>
#include <utility>
#include <cstring>
#include <string>
using namespace std;
const int maxn = 500010;
typedef long long ll;
int n;
int table[15];
string cardName[] = {"", "High Card", "Pair.", "Two Pairs", "Three of a Kind", "Full House", "Four of a kind",
"Straight", "Royal Straight"};
class Pair {
public:
string name;
string poker;
int mark[5];
int level;
int p[10];
Pair() {}
void resolve() {
unsigned long len = poker.length();
int cnt = 0;
for (int i = 0; i < len; ++i) {
if (poker[i] == 'A')
p[cnt++] = 1;
else if (poker[i] == 'J')
p[cnt++] = 11;
else if (poker[i] == 'Q')
p[cnt++] = 12;
else if (poker[i] == 'K')
p[cnt++] = 13;
else if (poker[i] == '1') {
if (i + 1 < len && poker[i + 1] == '0') {
++i;
p[cnt++] = 10;
} else p[cnt++] = 1;
} else p[cnt++] = poker[i] - '0';
}
sort(p, p + 5);
int sum = 0;
for (int i = 0; i < 5; ++i)
sum += p[i];
memset(table, 0, sizeof(table));
memset(mark, 0, sizeof(mark));
for (int i = 0; i < 5; ++i)
++table[p[i]];
level = 1;
mark[0] = sum;
for (int i = 4; i >= 0; --i) {
if (table[p[i]] >= 2) {
memset(mark, 0, sizeof(mark));
level = 2;
mark[0] = p[i];
mark[1] = sum - 2 * p[i];
break;
}
}
cnt = 0;
int higherPair = -1, lowerPair = 100;
for (int i = 4; i >= 0; --i) {
if (table[p[i]] >= 2) {
higherPair = max(p[i], higherPair);
lowerPair = min(lowerPair, p[i]);
++cnt;
}
}
if (higherPair != lowerPair && cnt >= 2) {
level = 3;
memset(mark, 0, sizeof(mark));
mark[0] = higherPair;
mark[1] = lowerPair;
mark[2] = sum - 2 * higherPair - 2 * lowerPair;
}
for (int i = 4; i >= 0; --i) {
if (table[p[i]] >= 3) {
memset(mark, 0, sizeof(mark));
level = 4;
mark[0] = p[i];
mark[1] = sum - 3 * p[i];
break;
}
}
for (int i = 4; i >= 0; --i) {
if (table[p[i]] >= 3) {
for (int j = 4; j >= 0; --j)
if (table[p[j]] == 2) {
level = 5;
memset(mark, 0, sizeof(mark));
mark[0] = p[i];
mark[1] = (sum - p[i] * 3) / 2;
break;
}
break;
}
}
for (int i = 4; i >= 0; --i) {
if (table[p[i]] >= 4) {
memset(mark, 0, sizeof(mark));
level = 6;
mark[0] = p[i];
mark[1] = sum - 4 * p[i];
break;
}
}
int straight = 0;
for (int i = 1; i <= 13; ++i) {
if (table[i]) {
for (int j = i; j < i + 5; ++j)
if (table[j])
++straight;
else break;
if (straight >= 5) {
memset(mark, 0, sizeof(mark));
level = 7;
mark[0] = i;
}
break;
}
}
if (table[1] && table[10] && table[11] && table[12] && table[13]) {
memset(mark, 0, sizeof(mark));
level = 8;
}
}
bool operator<(const Pair &rhs) const {
if (level == rhs.level) {
for (int i = 0; i < 3; ++i) {
if (mark[i] != rhs.mark[i])
return mark[i] > rhs.mark[i];
}
return rhs.name > name;
}
return level > rhs.level;
}
void print() {
cout << "Pokers: ";
for (int i = 0; i < 5; ++i)
cout << p[i] << " ";
cout << endl;
}
} pairs[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
while (cin >> n) {
for (int i = 0; i < n; ++i) {
cin >> pairs[i].name >> pairs[i].poker;
pairs[i].resolve();
}
sort(pairs, pairs + n);
for (int i = 0; i < n; ++i)
cout << pairs[i].name << "\n";
cout << flush;
}
return 0;
}