计蒜客 41408 Texas hold‘em Poker 模拟

Texas hold’em Poker

Code

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> PII;
#define LL long long
#define ULL unsigned long long
#define debug(a) cout << #a << " " << a << endl
#define de(a) cout << a << " "
#define fi first
#define se second
const int maxn = 150;
const int N = 1e5 + 7, M = N * 2;
const int inf = 0x3f3f3f3f;
const LL INF = 0xFFFFFFFFFF; //图接近 INT_MAX 时的初始化 判断时使用大于等于
const long long mod = 1e9 + 7;

inline long long read();

/**
 * 1 High Card 按和的大小
 * 2 Pair 手牌中有一对,同级别按对的大小,还一样按剩下的三张牌和的大小
 * 3 Two Pairs 手牌中有两对,同级别按两对中大的那对的大小,还一样按小的那对的大小,剩下的两张牌和的大小
 * 4 Three of a Kind 手牌中有三张一样,同级别按三张一样的牌的大小,还一样按剩下两张牌和的大小
 * 5 Full House 手牌中有一组三张一样,加上一组对子,同级别先按三张一样的大小排,再按两张一样的大小排
 * 6 Four of a Kind 手牌有四张一样,同级别按四张一样的大小排,再按剩余那张的大小排
 * 7 Straight 顺子,同级别按顺子最大的那张的大小排
 * 8 Royal Straight 10-J-Q-K-A
 */

struct Node {
    string name;
    int card[maxn]; //下标从1开始
    int level = -1; //表示等级
    int tag = -1; //本等级第二排序规则,-1表示本级别没有用到这个第二排序规则
    int tag2 = -1; // 两对的特殊规则
    int sum = 0; //表示手牌和或者第三排序规则

    bool operator<(const Node &w) const {
        if (level == w.level) {
            if (tag == w.tag) {
                if (tag2 == w.tag2) {
                    if (sum == w.sum) {
                        return name > w.name;
                    }
                    return sum < w.sum;
                }
                return tag2 < w.tag2;
            }
            return tag < w.tag;
        }
        return level < w.level;
    }
} node[N];

int n;

bool RoyalStraight(int a[]) {
    return a[1] == 1 && a[2] == 10 && a[3] == 11 && a[4] == 12 && a[5] == 13;
}

bool Straight(int a[]) {
    bool flag = true;
    for (int i = 2; i <= 5; i++) {
        if (a[i] - a[i - 1] != 1) {
            flag = false;
            break;
        }
    }
    return flag;
}

bool FourOfAKind(int a[]) {
    map<int, int> mp;
    for (int i = 1; i <= 5; i++) {
        mp[a[i]]++;
    }
    for (auto x:mp) {
        if (x.second == 4) return true;
    }
    return false;
}

bool FullHouse(int a[]) {
    map<int, int> mp;
    for (int i = 1; i <= 5; i++) {
        mp[a[i]]++;
    }
    int cnt = 0;
    for (auto x:mp) {
        if (x.second == 3) cnt++;
        if (x.second == 2) cnt++;
    }
    if (cnt == 2 && mp.size() == 2) return true; //注意这里map的大小要刚好为2,否则会把两对判进来
    else return false;
}

bool ThreeOfAKind(int a[]) {
    map<int, int> mp;
    for (int i = 1; i <= 5; i++) {
        mp[a[i]]++;
    }
    for (auto x:mp) {
        if (x.second == 3) return true;
    }
    return false;
}

bool TwoPairs(int a[]) {
    map<int, int> mp;
    for (int i = 1; i <= 5; i++) {
        mp[a[i]]++;
    }
    int cnt = 0;
    for (auto x:mp) {
        if (x.second == 2) cnt++;
    }

    if (cnt == 2) return true;
    else return false;
}

bool Pair(int a[]) {
    map<int, int> mp;
    for (int i = 1; i <= 5; i++) {
        mp[a[i]]++;
    }
    int cnt = 0;
    for (auto x:mp) {
        if (x.second == 2) return true;
    }
    return false;
}

void judge(Node &x) {
    int lv = -1, sum = 0;
    if (RoyalStraight(x.card)) {
        x.level = 8;
    }
    else if (Straight(x.card)) {
        x.level = 7;
        //tag是最大的那张牌
        x.tag = x.card[5];
    }
    else if (FourOfAKind(x.card)) {
        x.level = 6;
        //tag是和其他四张牌不一样的牌
        if (x.card[1] == x.card[2]) x.tag = x.card[1], x.tag2 = x.card[5];
        else x.tag = x.card[5], x.tag2 = x.card[1];
    }
    else if (FullHouse(x.card)) {
        x.level = 5;
        //tag是三张一样的大小,sum是两张一样的大小
        map<int, int> mp;
        for (int i = 1; i <= 5; i++) {
            mp[x.card[i]]++;
        }
        int cnt = 0;
        for (auto idx:mp) {
            if (idx.second == 3) x.tag = idx.first;
            else if (idx.second == 2) x.sum = idx.first;
        }
    }
    else if (ThreeOfAKind(x.card)) {
        x.level = 4;
        map<int, int> mp;
        for (int i = 1; i <= 5; i++) {
            mp[x.card[i]]++;
        }
        int cnt = 0;
        for (auto idx:mp) {
            if (idx.second == 3) x.tag = idx.first;
            if (idx.second == 1) x.sum += idx.first;
        }
    }
    else if (TwoPairs(x.card)) {
        x.level = 3;
        map<int, int> mp;
        for (int i = 1; i <= 5; i++) {
            mp[x.card[i]]++;
        }
        int cnt = 0;
        x.tag2 = inf;
        for (auto idx:mp) {
            if (idx.second == 2) x.tag = max(x.tag, idx.first), x.tag2 = min(x.tag2, idx.first);
            if (idx.second == 1) x.sum += idx.first;
        }
    }
    else if (Pair(x.card)) {
        x.level = 2;
        map<int, int> mp;
        for (int i = 1; i <= 5; i++) {
            mp[x.card[i]]++;
        }
        int cnt = 0;
        for (auto idx:mp) {
            if (idx.second == 2) x.tag = idx.first;
            if (idx.second == 1) x.sum += idx.first;
        }
    }
    else {
        //High Card
        x.level = 1;
        for (int i = 1; i <= 5; i++) x.sum += x.card[i];
    }


}

bool cmp(int a, int b) {
    return a < b;
}

void solve() {
    for (int i = 1; i <= n; i++) {
        node[i].level = -1, node[i].tag = -1, node[i].tag2 = -1, node[i].sum = 0;
        char cards[maxn];
        string name;
        cin >> name;
        scanf("%s", cards);
        node[i].name = name;
        //转化为数字
        int pos = 1;
        for (int j = 0; j < strlen(cards); j++) {
//            debug(pos);
            bool ten = false;
            if (cards[j] == 'A') node[i].card[pos] = 1;
            else if (cards[j] == '1' && j < strlen(cards) - 1 && cards[j + 1] == '0')
                node[i].card[pos] = 10, ten = true;
            else if (cards[j] == 'J') node[i].card[pos] = 11;
            else if (cards[j] == 'Q') node[i].card[pos] = 12;
            else if (cards[j] == 'K') node[i].card[pos] = 13;
            else {
                node[i].card[pos] = cards[j] - '0';
            }
            if (ten) j++;
            pos++;
        }
        //对每个人的手牌排序
        sort(node[i].card + 1, node[i].card + 1 + 5, cmp);

        judge(node[i]);
//        printf("level=%d tag=%d tag2=%d sum=%d\n", node[i].level, node[i].tag, node[i].tag2, node[i].sum);
    }

    sort(node + 1, node + 1 + n);
    for (int i = n; i >= 1; i--) {
        cout << node[i].name << '\n';
    }

}


int main() {

//    freopen("../input.txt", "r", stdin);
//    freopen("../output.txt", "w", stdout);

//	ios::sync_with_stdio(false);

    while (~scanf("%d", &n)) {
        solve();
    }


    return 0;
}


/*
数组开够了吗 开到上界的n+1次方
初始化了吗
*/







inline LL read() {
    char ch = getchar();
    LL p = 1, data = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-')p = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        data = data * 10 + (ch ^ 48);
        ch = getchar();
    }
    return p * data;
}

Test Case

22
1.1 10JQKA
1.2 10JQKA
2.1 34567
2.2 23456
3.1 55553
3.2 55552
3.3 44443
3.4 44442
4.1 44422
4.2 33322
4.3 333AA
5.1 333JK
5.2 33312
5.3 222JK
6.1 KKQQ1
6.2 KKJJ3
6.3 QQJJ2
7.1 KK234
7.2 KKA23
7.3 QQKJ10
8.1 246810
8.2 A3579
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值