寻找最大葫芦
1. 标签
模拟题
2. 题意
- 给定一个数组代表一组牌,数组中由整数组成,现在需要查找出一种叫做“葫芦”的牌型,“葫芦”由五张牌组成,包括三张一样的牌 A 和两张一样的牌 B,比如(5, 5, 5, 6, 6)。
- 组成“葫芦”的牌的面值加起来不能大于给定的最大值,在这里牌的面值的大小表示为:A > K > Q > J > 10 > 9 > 8 > 7 > 6 > 5 > 4 > 3 > 2,A 的牌值为1,K 为 13,以此类推,类似平时玩的扑克规则。
- 现在要求我们找到最大的“葫芦”,在这里“葫芦”的大小比较方式是根据满足“葫芦”的 A 和 B 来比较的,比如对于“葫芦”(A1, B1)和 (A2, B2), 如果 A1 > A2, 那么第一个对应的牌型大,如果 A1 == A2, 那么就对比 B1 和 B2,哪个大的对应的牌型也就大。
- 给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面,如果找不到符合条件的“葫芦”,则输出“0,0”。
3. 理解
我们需要找到一组牌中符合“葫芦”规则的最大组合,并且这组牌的面值之和不能超过给定的最大值 max。具体来说,“葫芦”由三张相同牌面值的牌 A 和两张相同牌面值的牌 b 组成。如果有多组符合条件的“葫芦”,我们需要选择其中最大的组合。
3. 题解
对于给定的数组,可以先去重,获得唯一的数组格式,还得统计每个数字出现的次数,这样可以判定是否满足“葫芦”的条件,对于获取的结果再进行对比,获得最大的“葫芦”牌型。在这个过程中,可以借助 STL 库中的 map 数据结构,可以大大减少去重和排序的步骤,对于 A 的情况,需要进行特殊的判断才能顺利通过。
- 统计牌面值数量: 遍历输入的牌数组,使用 std::map<int, int> 统计每种牌面值的数量。
- 查找符合条件的“葫芦”:遍历 map,对于每个牌面值 x1,如果其数量 y1 大于等于 3,则继续查找其他牌面值 x2,使得 x2 的数量 y2 大于等于 2,并且 x1 和 x2 不同。
- 计算 x1 * 3 + x2 * 2 的和,如果小于等于 max,则更新当前的最大“葫芦”组合。
- 处理特殊牌面值 A: 由于 A 的牌面值为 1,但在比较时 A 最大,因此需要特殊处理。
- 返回结果: 将找到的最大“葫芦”组合转换为输出格式。
#include <iostream>
#include <vector>
#include <map>
std::vector<int> solution(int n, int max, const std::vector<int>& array) {
std::map<int, int> mp;
for(auto x : array) mp[x]++;
std::pair<int, int> res ={0, 0};
for(auto [x1, y1]:mp) {
if(y1 >= 3) {
for(auto [x2, y2] : mp) {
if(y2 >= 2 &&x1 != x2 && x1 * 3 + x2 * 2 <= max) {
int x = x1, z = x2;
if(x == 1) x = 14;
if(z == 1) z = 14;
std::pair<int,int> tmp = {x, z};
res = std::max(res, tmp);
}
}
}
}
std::vector<int> ans;
ans.push_back(res.first == 14 ? 1 : res.first);
ans.push_back(res.second == 14 ? 1 : res.second);
// std::cout << ans[0] << ans[1] << '\n';
return ans;
}