寻找最大葫芦 | 豆包MarsCode AI 刷题

45 阅读4分钟

问题描述

在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 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最小。

解决这个问题的关键在于:

  1. 统计每张牌出现的次数。
  2. 找到可以组成“葫芦”的三张牌(牌面值出现至少3次)。
  3. 找到可以组成“葫芦”的两张牌(牌面值出现至少2次)。
  4. 确保组成“葫芦”的五张牌的牌面值之和不超过 max。
  5. 在所有可能的“葫芦”牌型中,找到牌面值最大的组合。

知识总结:

  • 在处理这类问题时,计数数组是一个非常有用的工具,它可以帮助我们快速统计各个元素的出现次数。
  • 对于特殊情况的优先处理(如牌面值为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 刷题工具可以提供即时反馈,帮助用户快速定位问题所在。
  • 结合其他学习资源,如在线教程、讨论区等,可以更全面地理解问题和解题方法。
  • 定期回顾和总结刷题经验,可以帮助巩固知识点,并提高解题效率。