题目链接:https://nanti.jisuanke.com/t/41408
输入各个玩家的姓名和手中持有的扑克牌,根据玩家的手中扑克牌的大小(规则如题)对玩家从大到小排序。如果有玩家的牌一样,这些玩家就按照姓名的字典序从小到大排序。最后输出排序后的玩家姓名。
模拟题,基本上没有什么难点,只是这道题模拟的规模相对比较大,如果不注意细节就会比较容易犯错。下面是题目中用到的思路:
黑历史记录:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define Mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
struct Person {
string name;
int pork[10];
int maxx[10];
int ranking;
}p[maxn];
int n;
string card;
map<string, int> vis;
bool cmp(Person &A, Person &B) {
if (A.ranking == B.ranking) {
for (int i = 1; i <= 5; i++) {
if (A.maxx[i] != B.maxx[i]) {
return A.maxx[i] > B.maxx[i];
}
}
return A.name < B.name;
} else {
return A.ranking > B.ranking;
}
}
void pre(int *a, int *b) {
int idx = 0;
for (int i = 0; i < card.length(); i++){
if (card[i] == 'A') {
a[++idx] = 1;
} else if (card[i] == 'J'){
a[++idx] = 11;
} else if (card[i] == 'Q'){
a[++idx] = 12;
} else if (card[i] == 'K'){
a[++idx] = 13;
} else if (card[i] == '1'){
a[++idx] = 10;
i++;
} else {
a[++idx] = card[i] - '0';
}
}
sort(a + 1, a + idx + 1);
for (int i = 1; i <= 5; i++)
b[i] = 0;
}
bool isRoyal(int *a, int *b) {
int idx = 0;
if (a[++idx] != 1) return false;
for (int i = 10; i < 14; i++)
if (a[++idx] != i) return false;
return true;
}
bool isStraight(int *a, int *b) {
for (int i = 1;i < 5; i++)
if ((a[i] + 1) != a[i + 1])
return false;
b[1] = a[5];
return true;
}
bool isFour(int *a, int *b) {
int cnt[15], ans;
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= 5; i++) cnt[a[i]]++;
for (int i = 1; i < 15; i++)
if (cnt[i] == 4) {
b[1] = i;
for (int j = 1; j <= 5; j++) if (a[j] != i) {
b[2] = a[j];
break;
}
return true;
}
return false;
}
bool isFull(int *a, int *b) {
int cnt[15], num_1 = 0, num_2 = 0;
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= 5; i++) cnt[a[i]]++;
for (int i = 1; i < 15; i++) {
if (cnt[i] == 3) num_1 = i;
else if (cnt[i] == 2) num_2 = i;
}
if (num_1 && num_2) {
b[1] = num_1;
b[2] = num_2;
return true;
}
return false;
}
bool isThree(int *a, int *b) {
int cnt[15], num_1 = 0, num_2[3], num_3 = 0;
memset(cnt, 0, sizeof(cnt));
memset(num_2, 0, sizeof(num_2));
for (int i = 1; i <= 5; i++) cnt[a[i]]++;
for (int i = 1; i < 15; i++) {
if (cnt[i] == 3) num_1 = i;
else if (cnt[i] == 1) num_2[++num_3] = i;
}
if (num_1) {
b[1] = num_1;
b[2] = num_2[1] + num_2[2];
return true;
}
return false;
}
bool isTwoPairs(int *a, int *b) {
int cnt[15], num_1[3], num_2 = 0, num_3 = 0;
memset(cnt, 0, sizeof(cnt));
memset(num_1, 0, sizeof(num_1));
for (int i = 1; i <= 5; i++) cnt[a[i]]++;
for (int i = 1; i < 15; i++) {
if (cnt[i] == 2) num_1[++num_3] = i;
else if (cnt[i] == 1) num_2 = i;
}
if (num_3 == 2) {
b[1] = num_1[2];
b[2] = num_1[1];
b[3] = num_2;
return true;
}
return false;
}
bool isPair(int *a, int *b) {
int cnt[15], num_1 = 0, num_2[4], num_3 = 0;
memset(cnt, 0, sizeof(cnt));
memset(num_2, 0, sizeof(num_2));
for (int i = 1; i <= 5; i++) cnt[a[i]]++;
for (int i = 1; i < 15; i++) {
if (cnt[i] == 2) num_1 = i;
else if (cnt[i] == 1) num_2[++num_3] = i;
}
if (num_1) {
b[1] = num_1;
b[2] = num_2[1] + num_2[2] + num_2[3];
return true;
}
return false;
}
void judge(Person &p) {
if (isRoyal(p.pork, p.maxx)) {
p.ranking = 8;
} else if (isStraight(p.pork, p.maxx)) {
p.ranking = 7;
} else if (isFour(p.pork, p.maxx)) {
p.ranking = 6;
} else if (isFull(p.pork, p.maxx)) {
p.ranking = 5;
} else if (isThree(p.pork, p.maxx)) {
p.ranking = 4;
} else if (isTwoPairs(p.pork, p.maxx)) {
p.ranking = 3;
} else if (isPair(p.pork, p.maxx)) {
p.ranking = 2;
} else {
p.ranking = 1;
for (int i = 1; i <= 5; i++) {
p.maxx[1] += p.pork[i];
}
}
}
int main()
{
// freopen("t.txt", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> n) {
for (int i = 1; i <= n; i++) {
cin >> p[i].name >> card;
pre(p[i].pork, p[i].maxx);
judge(p[i]);
}
sort(p + 1, p + n + 1, cmp);
for (int i = 1; i <= n; i++)
cout << p[i].name << endl;
}
return 0;
}