H. Texas hold'em Poker(2019ICPC区域网络赛沈阳站)

锺离辰沛
2023-12-01

题目链接:https://nanti.jisuanke.com/t/41408

题目大意

输入各个玩家的姓名和手中持有的扑克牌,根据玩家的手中扑克牌的大小(规则如题)对玩家从大到小排序。如果有玩家的牌一样,这些玩家就按照姓名的字典序从小到大排序。最后输出排序后的玩家姓名。

题目分析

模拟题,基本上没有什么难点,只是这道题模拟的规模相对比较大,如果不注意细节就会比较容易犯错。下面是题目中用到的思路:

  • 划分等级。给题目中提及到的套路等级规定相应的等级,判断完等级之后,只需要做一次排序就可以得到最后的答案。
  • 分模块判断。对于玩家手中的牌,从大到小的等级顺序按模块判断手牌的等级。另外定义一个牌的特征数组,用于同等级扑克牌的比较。

黑历史记录:

  • 又犯了大一天梯赛选拔赛时的错误,因为没有看清题意,看完样例直接开始做题,没有进行多组样例的输入
  • 没有看清楚题目。对于单张不同的牌,都是通过求和来比较大小,而不是通过我们平常那样。
  • 数组越界。开了大小为15的数组,却访问了下标为15的元素,怕不是石乐志了。

代码如下

#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;
}

 类似资料: