当前位置:首页 > 洛谷题解 > 洛谷P1148题解:拱猪游戏计分系统实现

洛谷P1148题解:拱猪游戏计分系统实现

16小时前洛谷题解41

截图未命名.jpg 洛谷P1148题解:拱猪游戏计分系统实现 C++实现 洛谷题解 枚举 第1张

一、问题分析

这道题目要求我们根据拱猪游戏的复杂计分规则,计算四位玩家在牌局结束时的得分。需要考虑多种特殊情况,如红心牌是否集中、加倍牌的影响等。

二、解题思路

1.解析输入数据,记录每位玩家持有的计分牌

2.检查红心牌是否全部集中在同一玩家手中

3.根据不同的计分规则计算基础分数

4.处理加倍牌(C10)的特殊情况

5.综合计算最终得分并输出

三、完整代码

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <sstream>
using namespace std;

// 红心牌对应的分值
const map<string, int> HEART_SCORES = {
    {"H1", -50}, {"H2", -2}, {"H3", -3}, {"H4", -4}, {"H5", -5},
    {"H6", -6}, {"H7", -7}, {"H8", -8}, {"H9", -9}, {"H10", -10},
    {"H11", -20}, {"H12", -30}, {"H13", -40}
};

// 计算单个玩家的基础分数
int calculateBaseScore(const vector<string>& cards, bool allHeartsInOne) {
    int score = 0;
    bool hasS12 = false, hasD11 = false;
    int heartCount = 0;
    
    for (const auto& card : cards) {
        if (card == "S12") {
            score += allHeartsInOne ? 0 : -100;
            hasS12 = true;
        } else if (card == "D11") {
            score += allHeartsInOne ? 0 : 100;
            hasD11 = true;
        } else if (HEART_SCORES.count(card)) {
            heartCount++;
        }
    }
    
    // 处理红心牌分数
    if (allHeartsInOne && heartCount == 13) {
        score += 200;
        if (hasS12 && hasD11) {
            score = 500; // 覆盖之前的200分
        }
    } else {
        // 非集中红心的情况
        for (const auto& card : cards) {
            if (HEART_SCORES.count(card)) {
                score += HEART_SCORES.at(card);
            }
        }
    }
    
    return score;
}

int main() {
    string line;
    while (true) {
        vector<vector<string>> players(4);
        bool allZero = true;
        
        // 读取四位玩家的牌
        for (int i = 0; i < 4; ++i) {
            getline(cin, line);
            istringstream iss(line);
            int count;
            iss >> count;
            if (count != 0) allZero = false;
            
            string card;
            for (int j = 0; j < count; ++j) {
                iss >> card;
                players[i].push_back(card);
            }
        }
        
        if (allZero) break;
        
        // 检查红心牌是否全部集中在同一玩家
        bool allHeartsInOne = false;
        int heartPlayer = -1;
        for (int i = 0; i < 4; ++i) {
            int heartCount = 0;
            for (const auto& card : players[i]) {
                if (HEART_SCORES.count(card)) heartCount++;
            }
            if (heartCount == 13) {
                allHeartsInOne = true;
                heartPlayer = i;
                break;
            }
        }
        
        // 计算每位玩家的分数
        vector<int> scores(4, 0);
        for (int i = 0; i < 4; ++i) {
            scores[i] = calculateBaseScore(players[i], allHeartsInOne && (i == heartPlayer));
            
            // 检查加倍牌(C10)的情况
            bool hasC10 = false;
            for (const auto& card : players[i]) {
                if (card == "C10") {
                    hasC10 = true;
                    break;
                }
            }
            
            if (hasC10) {
                if (players[i].size() == 1) {
                    scores[i] = 50; // 只有C10牌
                } else {
                    scores[i] *= 2; // 加倍
                }
            }
        }
        
        // 输出结果
        for (int i = 0; i < 4; ++i) {
            if (i != 0) cout << " ";
            if (scores[i] > 0) cout << "+";
            cout << scores[i];
        }
        cout << endl;
    }
    return 0;
}


四、代码解析

  1. 数据结构设计‌:使用map存储红心牌的分值对应关系

  2. 输入处理‌:读取每位玩家的持牌情况

  3. 红心牌检查‌:判断是否所有红心牌集中在同一玩家

  4. 基础分数计算‌:根据规则计算不含加倍的基础分

  5. 加倍处理‌:检查C10牌并应用加倍规则

  6. 结果输出‌:格式化输出四位玩家的得分

五、实际应用

棋牌游戏开发、竞赛评分系统、游戏规则引擎、自动化测试


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

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