[简单]
问题描述
在一场经典的德州扑克游戏中,有一种牌型叫做“葫芦”。“葫芦”由五张牌组成,其中包括三张相同牌面值的牌 a 和另外两张相同牌面值的牌 bb。如果两个人同时拥有“葫芦”,我们会优先比较牌 aa 的大小,若牌 a 相同则再比较牌 b 的大小,牌面值的大小规则为:1 (A) > K > Q > J > 10 > 9 > ... > 2,其中 1 (A) 的牌面值为1,K 为13,依此类推。
在这个问题中,我们对“葫芦”增加了一个限制:组成“葫芦”的五张牌牌面值之和不能超过给定的最大值 max。
给定一组牌,你需要找到符合规则的最大的“葫芦”组合,并输出其中三张相同的牌面和两张相同的牌面。如果找不到符合条件的“葫芦”,则输出 “0, 0”。
测试样例
样例1:
输入:
n = 9, max = 34, array = [6, 6, 6, 8, 8, 8, 5, 5, 1]
输出:[8, 5]
说明:array数组中可组成4个葫芦,分别为[6,6,6,8,8],[6,6,6,5,5],[8,8,8,6,6],[8,8,8,5,5]。其中[8,8,8,6,6]的牌面值为36,大于34不符合要求。剩下的3个葫芦的大小关系为[8,8,8,5,5]>[6,6,6,8,8]>[6,6,6,5,5],故返回[8,5]
样例2:
输入:
n = 9, max = 37, array = [9, 9, 9, 9, 6, 6, 6, 6, 13]
输出:[6, 9]
说明:可组成2个葫芦,分别为[9,9,9,6,6]和[6,6,6,9,9],由于[9,9,9,6,6]的牌面值为39,大于37,故返回[6,9]
样例3:
输入:
n = 9, max = 40, array = [1, 11, 13, 12, 7, 8, 11, 5, 6]
输出:[0, 0]
说明:无法组成任何葫芦,故返回[0,0]
样例4:
输入:
n = 6, max = 50, array = [13, 13, 13, 1, 1, 1]
输出:[1, 13]
说明:可组成两个葫芦,分别为[A,A,A,K,K]和[K,K,K,A,A],两者牌面值都小于50,故都合法。因为三张相同牌面值的A > K,故[A,A,A,K,K]比[K,K,K,A,A]要大,返回[1,13]
题解
比较偏模拟题吧。但是 marscode 这里的简单题明显比 leetcode 的要难,有一点点竞赛打卡提的味道(当然远远不够的)。
基本思路是:
- 统计所有牌的数量
- 对所有牌型根据牌面值降序排序得到排序后的牌型列表
- 如果出现 牌,按照牌面值排序会被排到最后,但是实际上它是牌型比较的时候最大的牌,所以如果牌型列表的最后一张牌是 ,则手动放到列表最前
- 两层
for-loop嵌套循环尝试在有序牌型列表中找到第一个牌型字典序最大的“葫芦牌”,因为现在牌型列表已经根据牌型排序的字典序排序(也就是不是根据牌面值排序,现在 会放到第一),所以第一层循环负责固定葫芦牌的第一张牌,第二层循环负责固定葫芦牌的第二张牌,两张牌不能相同,同时注意判断所选牌的数量是否足够,最后判断此次组合的葫芦牌是否超过给定的最大值 - 在嵌套循环中第一个找到的葫芦牌组合直接返回答案,它就是牌型字典序最大的葫芦牌
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <stdio.h>
std::vector<int> solution(int n, int max, const std::vector<int>& nums) {
// Edit your code here
if (n < 5) return {0, 0};
// 牌型比较是字典序比较,因此牌型组合遍历的顺序是固定A遍历B
std::unordered_map<int, int> cnt;
for (const int& num : nums) cnt[num]++;
// divide cards into A-type and B-type deck
std::vector<int> cardList;
for (auto iter = cnt.begin(), end = cnt.end(); iter != end; ++iter)
cardList.emplace_back(iter->first);
std::sort(cardList.begin(), cardList.end(), std::greater<int>());
if (cardList.back() == 1) {
// put card Ace to the first position
cardList.pop_back();
cardList.insert(cardList.begin(), 1);
}
n = cardList.size();
for (int i = 0; i < n; ++i) {
if (cnt[cardList[i]] < 3) continue;
for (int j = 0; j < n; ++j) {
if (cnt[cardList[j]] < 2) continue;
if (j == i) continue;
if (cardList[i] * 3 + cardList[j] * 2 <= max)
return {cardList[i], cardList[j]};
}
}
return {0, 0};
}
int main() {
// Add your test cases here
std::vector<int> result;
result = solution(9, 34, {6, 6, 6, 8, 8, 8, 5, 5, 1});
printf("%d, %d\n", result[0], result[1]);
std::cout << (result == std::vector<int>{8, 5}) << std::endl;
result = solution(9, 37, {9, 9, 9, 9, 6, 6, 6, 6, 13});
printf("%d, %d\n", result[0], result[1]);
std::cout << (result == std::vector<int>{6, 9}) << std::endl;
result = solution(9, 40, {1, 11, 13, 12, 7, 8, 11, 5, 6});
printf("%d, %d\n", result[0], result[1]);
std::cout << (result == std::vector<int>{0, 0}) << std::endl;
return 0;
}