问题描述
在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 a 和另外两张相同牌面值的牌 b。如果两个人同时拥有“葫芦”,我们会优先比较牌 a 的大小,若牌 a 相同则再比较牌 b 的大小。
在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 max。牌面值的大小规则为: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]
题目解析:
这个问题要求我们在给定的牌组中找到最大的“葫芦”牌型,同时牌面值之和不能超过给定的最大值 max。首先,我们需要了解“葫芦”牌型的定义,即三张相同牌面值的牌加上另外两张相同牌面值的牌。在德州扑克中,牌面值的大小规则是固定的,A最大,2最小。
解决这个问题的关键在于:
- 统计每张牌出现的次数。
- 找到可以组成“葫芦”的三张牌(牌面值出现至少3次)。
- 找到可以组成“葫芦”的两张牌(牌面值出现至少2次)。
- 确保组成“葫芦”的五张牌的牌面值之和不超过 max。
- 在所有可能的“葫芦”牌型中,找到牌面值最大的组合。
知识总结:
- 在处理这类问题时,计数数组是一个非常有用的工具,它可以帮助我们快速统计各个元素的出现次数。
- 对于特殊情况的优先处理(如牌面值为1的情况)可以简化后续的查找过程。
- 代码中使用了嵌套循环来找到合适的牌面值组合,外层循环寻找三张相同的牌,内层循环寻找两张相同的牌。
相关代码
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
vector<int> solution(int n, int max_sum, vector<int> array) {
// 创建一个计数数组来存储0到13的数字出现的频率
vector<int> count(14, 0);
// 统计每个数字在数组中的出现次数
for (int num : array) {
count[num]++;
}
// 初始化标志和索引
int first_index = -1;
int second_index = -1;
// 特殊处理数字1
if (count[1] >= 3) {
first_index = 1;
for (int j = 13; j >= 0; j--) {
if (count[j] >= 2 && j != first_index) {
if (3 * first_index + 2 * j <= max_sum) {
second_index = j;
return {first_index, second_index};
}
}
}
}
// 从高到低找到第一个出现至少3次的数字
for (int i = 13; i >= 0; i--) {
if (count[i] >= 3 && first_index != 0) {
first_index = i;
if (count[1] >= 2 && first_index != 1) {
second_index = 1;
if (3 * first_index + 2 * second_index <= max_sum) {
return {first_index, second_index};
}
}
for (int j = 13; j >= 0; j--) {
if (count[j] >= 2 && j != first_index) {
if (3 * first_index + 2 * j <= max_sum) {
second_index = j;
return {first_index, second_index};
}
}
}
first_index = -1;
}
}
return {0, 0};
}
int main() {
// 测试用例
vector<int> result1 = solution(9, 34, {6, 6, 6, 8, 8, 8, 5, 5, 1});
cout << (result1 == vector<int>{8, 5}) << endl;
vector<int> result2 = solution(9, 37, {9, 9, 9, 9, 6, 6, 6, 6, 13});
cout << (result2 == vector<int>{6, 9}) << endl;
vector<int> result3 = solution(9, 40, {1, 11, 13, 12, 7, 8, 11, 5, 6});
cout << (result3 == vector<int>{0, 0}) << endl;
return 0;
}
学习计划:
- 制定刷题计划时,可以从简单到复杂逐步提高难度,这样可以逐渐建立信心并掌握基础。
- 对于错题,应该进行详细的分析,找出错误的原因,并总结出解题的规律。
- 刷题时,应该注意不同类型题目的解题方法,并尝试将它们应用到其他问题上。
工具运用:
- AI 刷题工具可以提供即时反馈,帮助用户快速定位问题所在。
- 结合其他学习资源,如在线教程、讨论区等,可以更全面地理解问题和解题方法。
- 定期回顾和总结刷题经验,可以帮助巩固知识点,并提高解题效率。