当前位置:首页 > 牛客题解 > 牛客网4874题:C++实现扑克牌比大小的完整解析

牛客网4874题:C++实现扑克牌比大小的完整解析

1周前 (09-10)牛客题解74

截图未命名.jpg 牛客网4874题:C++实现扑克牌比大小的完整解析 牛客题解 扑克牌 哈希表 STL应用 枚举 第1张

一、题目解读

本题要求实现一个扑克牌比较系统,模拟"炸金花"游戏的牌型判定规则。核心难点在于:

  1. 多维度牌型识别(6种牌型)

  2. 特殊组合处理(王炸、炸弹)

  3. 权重系统设计(3最小,JOKER最大)

  4. 异常输入处理(ERROR)

二、解题思路分析

采用"分类处理+优先级队列"思想:

  1. 分层判定:按照牌型优先级顺序检查(王炸>炸弹>其他)

  2. 权重映射哈希表存储牌面基础权重

  3. 类型识别

    • 基于STL算法(all_of)判断炸弹

    • 差值法验证顺子连续性

三、解题步骤详解

  1. 输入解析

    • 使用stringstream分割输入字符串

    • 处理可能存在的空格问题

  2. 牌型检测

  3. 胜负判定

    • 优先处理特权牌型(第25-28行)

    • 同类型比较基础权重(第31-33行)


四、完整代码实现

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <sstream>
#include <algorithm>

using namespace std;

// 扑克牌权重映射表
const unordered_map<string, int> CARD_RANK = {
    {"3", 1}, {"4", 2}, {"5", 3}, {"6", 4},
    {"7", 5}, {"8", 6}, {"9", 7}, {"10", 8},
    {"J", 9}, {"Q", 10}, {"K", 11}, {"A", 12},
    {"2", 13}, {"joker", 14}, {"JOKER", 15}
};

// 牌型枚举
enum CardType {
    SINGLE = 1,    // 个子
    PAIR,          // 对子
    TRIPLE,        // 三个
    BOMB,          // 炸弹
    STRAIGHT,      // 顺子
    JOKER_PAIR     // 对王
};

// 获取牌型和权重
pair<CardType, int> getCardType(const vector<string>& cards) {
    int size = cards.size();
    
    // 检查对王
    if (size == 2 && cards[0] == "joker" && cards[1] == "JOKER") {
        return {JOKER_PAIR, 15};
    }
    
    // 检查炸弹
    if (size == 4 && all_of(cards.begin(), cards.end(), 
        [&](const string& s){return s == cards[0];})) {
        return {BOMB, CARD_RANK.at(cards[0])};
    }
    
    // 检查顺子
    if (size == 5) {
        bool is_straight = true;
        for (int i = 0; i < 4; ++i) {
            if (CARD_RANK.at(cards[i+1]) - CARD_RANK.at(cards[i]) != 1) {
                is_straight = false;
                break;
            }
        }
        if (is_straight) {
            return {STRAIGHT, CARD_RANK.at(cards[0])};
        }
    }
    
    // 检查三个
    if (size == 3 && cards[0] == cards[1] && cards[1] == cards[2]) {
        return {TRIPLE, CARD_RANK.at(cards[0])};
    }
    
    // 检查对子
    if (size == 2 && cards[0] == cards[1]) {
        return {PAIR, CARD_RANK.at(cards[0])};
    }
    
    // 默认是个子
    return {SINGLE, CARD_RANK.at(cards[0])};
}

// 比较两手牌
string compareCards(const string& input) {
    size_t pos = input.find('-');
    if (pos == string::npos) return "ERROR";
    
    vector<string> cards1, cards2;
    istringstream iss(input.substr(0, pos));
    string card;
    while (iss >> card) cards1.push_back(card);
    
    iss = istringstream(input.substr(pos + 1));
    while (iss >> card) cards2.push_back(card);
    
    auto [type1, rank1] = getCardType(cards1);
    auto [type2, rank2] = getCardType(cards2);
    
    // 处理特殊牌型
    if (type1 == JOKER_PAIR) return input.substr(0, pos);
    if (type2 == JOKER_PAIR) return input.substr(pos + 1);
    if (type1 == BOMB && type2 != BOMB) return input.substr(0, pos);
    if (type2 == BOMB && type1 != BOMB) return input.substr(pos + 1);
    
    // 同类型比较
    if (type1 == type2) {
        return (rank1 > rank2) ? input.substr(0, pos) : input.substr(pos + 1);
    }
    
    return "ERROR";
}

int main() {
    string input;
    getline(cin, input);
    cout << compareCards(input) << endl;
    return 0;
}


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。