洛谷P1148题解:拱猪游戏计分系统实现
一、问题分析
这道题目要求我们根据拱猪游戏的复杂计分规则,计算四位玩家在牌局结束时的得分。需要考虑多种特殊情况,如红心牌是否集中、加倍牌的影响等。
二、解题思路
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; }
四、代码解析
数据结构设计:使用map存储红心牌的分值对应关系
输入处理:读取每位玩家的持牌情况
红心牌检查:判断是否所有红心牌集中在同一玩家
基础分数计算:根据规则计算不含加倍的基础分
加倍处理:检查C10牌并应用加倍规则
结果输出:格式化输出四位玩家的得分
五、实际应用
棋牌游戏开发、竞赛评分系统、游戏规则引擎、自动化测试
原创内容 转载请注明出处