问题描述
在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 aa 和另外两张相同牌面值的牌 bb。如果两个人同时拥有“葫芦”,我们会优先比较牌 aa 的大小,若牌 aa 相同则再比较牌 bb 的大小。
在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 maxmax。牌面值的大小规则为:A > K > Q > J > 10 > 9 > ... > 2,其中 A 的牌面值为1,K 为13,依此类推。
给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。
测试样例
样例1:
输入:
n = 9, max = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1]
输出:[8, 5]
样例2:
输入:
n = 9, max = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13]
输出:[6, 9]
样例3:
输入:
n = 9, max = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6]
输出:[0, 0]
问题理解
我们需要在给定的牌中找到一个“葫芦”组合,即三张相同牌面值的牌 a 和两张相同牌面值的牌 b,并且这个组合的牌面值之和不能超过给定的最大值 max。如果存在多个符合条件的组合,我们需要选择牌面值最大的组合。
-
统计每种牌面值的出现次数:遍历输入的牌数组,哈希表 记录每种牌面值的出现次数。
-
筛选符合条件的牌面值:遍历统计结果,将出现次数大于等于3的牌面值及其出现次数存入
triples向量,将出现次数大于等于2的牌面值及其出现次数存入pairs向量。 -
计算和判断:
- 遍历
triples和pairs,计算每种可能的“葫芦”组合的牌面值之和。 - 如果组合的牌面值之和不超过
max,则更新当前的最大组合。 - 在更新最大组合时,需要考虑牌面值的大小规则(A > K > Q > J > 10 > 9 > ... > 2)。
- 遍历
-
返回结果:如果找到符合条件的最大组合,返回该组合的牌面值;否则返回
[0, 0]。
代码
#include <iostream>
#include <unordered_map>
#include <vector>
std::vector<int> solution(int n, int max, const std::vector<int> &array) {
// if (n == 31 && max == 42)
// return {1, 13};
// if (n == 17 && max == 87)
// return {1, 13};
// Edit your code here
// 1. 统计每种牌面值的出现次数
std::unordered_map<int, int> count;
for (int card : array) {
count[card]++;
}
// 2. 筛选符合条件的牌面值
std::vector<std::pair<int, int>>
triples; // 存储出现次数大于等于3的牌面值及其出现次数
std::vector<std::pair<int, int>>
pairs; // 存储出现次数大于等于2的牌面值及其出现次数
for (auto &[card, cnt] : count) {
if (cnt >= 3) {
triples.push_back({card, cnt});
}
if (cnt >= 2) {
pairs.push_back({card, cnt});
}
}
// 3. 计算和判断
int max_a = 0, max_b = 0;
for (auto &[a, cnt_a] : triples) {
for (auto &[b, cnt_b] : pairs) {
if (a != b && 3 * a + 2 * b <= max) {
// 更新最大值
if (a == 1 && b != 1) {
if (max_a < 14 || (max_a == 14) && b > max_b) {
max_a = 14;
max_b = b;
}
} else if (a != 1 && b == 1) {
if (max_a < a || (max_a == a) && 14 > max_b) {
max_a = a;
max_b = 14;
}
} else if (a > max_a || (a == max_a && b > max_b)) {
max_a = a;
max_b = b;
}
}
}
}
// 4. 返回结果
if (max_a == 14)
max_a = 1;
if (max_b == 14)
max_b = 1;
if (max_a == 0 && max_b == 0) {
return {0, 0};
} else {
// if (max_a > max_b)
// return {max_a, max_b};
// return {max_b, max_a};
return {max_a, max_b};
}
return {0, 0};
}
int main() {
// Add your test cases here
std::vector<int> result1 = solution(9, 34, {6, 6, 6, 8, 8, 8, 5, 5, 1});
std::cout << (result1 == std::vector<int>{8, 5}) << std::endl;
std::vector<int> result2 = solution(9, 37, {9, 9, 9, 9, 6, 6, 6, 6, 13});
std::cout << (result2 == std::vector<int>{6, 9}) << std::endl;
std::vector<int> result3 = solution(9, 40, {1, 11, 13, 12, 7, 8, 11, 5, 6});
std::cout << (result3 == std::vector<int>{0, 0}) << std::endl;
return 0;
}
值得注意的是这里对于卡片A和14的值处理,这里要多加小心,AI在生成算法大纲上很好用,在细节上还是要自己写。