斗地主之顺子
题目描述
在斗地主扑克牌游戏中,扑克牌由小到大的顺序为:3,4,5,6,7,8,9,10,J,Q,K,A,2,玩家可以出的扑克牌阵型有:单张、对子、飞机、炸弹等。
其中顺子与同组牌型较为特殊:由至少5张按小到大连续递增的扑克牌组成,且不能包含2。例如:[3,4,5,6,7],(3,4,5,6,7,8,9,10,J,Q,K,A)等是有效顺子;而{J,Q,K,A,2}、{2,3,4,5,6}、{3,4,5,6,8}等都不是顺子。
给定一个包含13张牌的数组,如果有满足上述规则的顺子,请输出顺子。如果存在多个顺子,请每行输出一个顺子,需按顺序的大小(必须从小到大)依次输出。
如果没有满足上述规则的顺子,请输出“No”。
输入描述
13张任意顺序的扑克牌,每张扑克牌的数字用字符隔开,每张扑克牌的数字都是合法的,并且不包括大小王。
示例输入:29J234KA79A56
输出描述
满足顺子规则的牌型,按小到大的顺序逐行输出。如果没有满足规则的顺子,输出“No”。
示例1
输入:
29J234KA79A56
输出:
34567
说明:
13张牌中,可以组成的顺子只有1组:34567
示例2
输入:
29J1034KA7QA56
输出:
34567
910JQKA
说明:
13张牌中,可以组成2组顺子,从小到大分别为:34567 和 910JQKA
示例3
输入:
299934KA10QA56
输出:
No
说明:
13张牌中,无法组成顺子
题解
解题思路
这道题目要求我们从13张扑克牌中找出所有符合顺子规则的牌型。顺子的定义是由至少5张按顺序递增的牌组成,且牌中不能有2。以下是解题的关键步骤:
- 扑克牌的数字映射:
- 扑克牌的数字从
3
到A
,2
不允许出现在顺子中。- 我们需要将输入的字符串转换为一组整数,并为
J
,Q
,K
,A
等字符指定具体的值:J
-> 11,Q
-> 12,K
-> 13,A
-> 14。- 统计牌的数量:
- 用一个数组
freq
来统计每个数字的出现次数。数组的索引对应扑克牌的数字(3-14
),我们将其映射到一个数组中。- 寻找顺子:
- 顺子必须是至少5张连续的牌。我们使用双指针方法来查找连续的非零牌,并检查其是否满足顺子的要求(至少5张连续的牌)。
- 输出结果:
- 找到符合要求的顺子后,按从小到大的顺序输出每一个顺子。如果没有顺子,输出 "No"。
解题步骤:
- 初始化一个数组
freq
,用来记录扑克牌的数量,数组长度为15(包括3到14,排除2)。- 遍历输入的牌,根据每张牌的字符映射到
freq
数组中的对应位置。- 使用双指针方法寻找符合顺子规则的牌型。
- 如果找到顺子,输出顺子;如果没有找到任何顺子,输出 "No"。
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
// 用于统计牌的数量
vector<int> freq(15, 0);
string line;
cin >> line;
for (char c: line) {
// 碰到 1 只能是 10, 碰到 0 忽略掉
if (c == '0') continue;
int idx = string("1JQKA").find(c);
if (idx == string::npos) { // 3 ~ 9
freq[c - '0']++;
} else {
freq[10 + idx]++;
}
}
vector<string> result;
for (int start = 3; start <= 10;) {
if (freq[start] == 0 && ++start) continue;
// 双指针方式组合顺子
int end = start;
while (end < freq.size() && freq[end] > 0) freq[end++]--;
// 顺子的牌的张数
int seqLength = end - start;
if (seqLength >= 5) { // 符合顺子要求,组合结果
string combination;
for (int c = start; c < end; c++) {
string POKER = "JQKA";
if (c == 10) {
combination += "10";
} else if (c >= 11) {
combination.push_back(POKER[c - 11]);
} else {
combination.push_back((char) (c + '0'));
}
}
result.push_back(combination);
}
}
if (result.empty()) {
cout << "No" << endl;
} else {
for (const auto &comb: result) {
cout << comb << endl;
}
}
return 0;
}
#面经##春招##秋招##华为od##C++#整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏
C++笔试真题题解 文章被收录于专栏
笔试真题题解