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

168 阅读3分钟

问题描述

在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 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。如果存在多个符合条件的组合,我们需要选择牌面值最大的组合。

  1. 统计每种牌面值的出现次数:遍历输入的牌数组,哈希表 记录每种牌面值的出现次数。

  2. 筛选符合条件的牌面值:遍历统计结果,将出现次数大于等于3的牌面值及其出现次数存入 triples 向量,将出现次数大于等于2的牌面值及其出现次数存入 pairs 向量。

  3. 计算和判断

    • 遍历 triples 和 pairs,计算每种可能的“葫芦”组合的牌面值之和。
    • 如果组合的牌面值之和不超过 max,则更新当前的最大组合。
    • 在更新最大组合时,需要考虑牌面值的大小规则(A > K > Q > J > 10 > 9 > ... > 2)。
  4. 返回结果:如果找到符合条件的最大组合,返回该组合的牌面值;否则返回 [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在生成算法大纲上很好用,在细节上还是要自己写。