洛谷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牌并应用加倍规则
结果输出:格式化输出四位玩家的得分
五、实际应用
棋牌游戏开发、竞赛评分系统、游戏规则引擎、自动化测试
原创内容 转载请注明出处
