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

30 阅读3分钟

今天带来解题分享!

数据结构准备: 首先,可以使用合适的数据结构来表示扑克牌,比如字典,将牌面值(如 'A'、'K' 等)映射到对应的数值(如 1、13 等),方便后续比较和计算。 牌型分析: 遍历给定的一组牌,统计每张牌出现的次数。可以通过一个字典来记录,键为牌面值,值为出现的次数。 寻找可能组成 “葫芦” 的牌型组合。遍历统计次数的字典,对于出现次数大于等于 3 的牌面值,将其作为三张相同牌面值的候选牌 𝑎。然后再在剩下的牌中寻找出现次数大于等于 2 的牌面值作为两张相同牌面值的候选牌 𝑏,这样就初步找到了可能的 “葫芦” 组合。 条件判断: 对于每一个找到的潜在 “葫芦” 组合,计算其五张牌牌面值之和,通过之前建立的牌面值到数值的映射来计算。 将计算出的和与给定的最大值 𝑚𝑎𝑥 进行比较,如果小于等于 𝑚𝑎𝑥,则该 “葫芦” 组合符合条件。 找出最大组合: 在所有符合条件的 “葫芦” 组合中,按照先比较牌 𝑎 的大小(根据牌面值到数值的映射),若牌 𝑎 相同则再比较牌 𝑏 的大小的规则,找出最大的 “葫芦” 组合。最后输出该最大 “葫芦” 组合中三张相同的牌面和两张相同的牌面,如果没有找到符合条件的 “葫芦”,则输出 “0, 0”。

部分代码展示

#include <bits/stdc++.h>

using namespace std;

vector solution(int n, int max, const vector& array) { map<int , int> p; for(auto t : array) if(t == 1) p[14] ++; else p[t] ++;

vector<int> a , b;
for(auto [k , v] : p)
    if(v >= 3) a.push_back(k) , b.push_back(k);
    else if(v >= 2) b.push_back(k);

sort(a.begin() , a.end() , greater<int>());
sort(b.begin() , b.end() , greater<int>());

心得

代码整体逻辑清晰明了。通过使用 map 数据结构有效地统计了牌面数字出现的次数,然后根据出现次数筛选出可能构成 “葫芦” 的三张相同牌和两张相同牌的候选集合 a 和 b,这种方式简洁直观地处理了牌型的初步分析。 对候选集合 a 和 b 进行排序,使得后续在寻找符合条件的 “葫芦” 时能够按照牌面大小顺序进行比较,有助于快速确定最大的 “葫芦” 组合,体现了对算法效率的一定考量。 代码结构较为规范,solution 函数专注于核心的解题逻辑,main 函数中则用于测试不同的输入情况,便于验证代码的正确性和完整性。

代码的可扩展性较差。例如,如果牌面的规则或者 “葫芦” 的定义发生变化,可能需要对多处代码进行修改。可以考虑将牌面的映射规则和牌型判断逻辑封装成独立的类或函数,提高代码的可维护性和扩展性。 对于输入数据的合法性校验缺失。如果输入的 nmax 或者 array 不符合预期(如 n 与 array 长度不匹配、max 为负数等),代码可能会出现错误或异常行为。应添加适当的数据校验部分,增强代码的健壮性。 在计算牌面总和时,对于 A(牌值为 14)的特殊处理略显生硬,可以考虑在牌面映射时就统一处理好这种特殊情况,使代码逻辑更加流畅。 代码中使用了 bits/stdc++.h 头文件,虽然方便,但在一些正式的项目或竞赛环境中可能不被允许,应尽量使用标准的头文件集合,以提高代码的通用性。

总体而言,通过完成这道题,对扑克牌牌型处理的算法设计有了更深入的理解,同时也认识到代码在功能性、健壮性和扩展性等方面需要综合考虑和不断优化,以适应更复杂多变的需求和环境。