斗地主之顺子

华为od机试

题目描述

在斗地主扑克牌游戏中,扑克牌由小到大的顺序为: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。以下是解题的关键步骤:

  1. 扑克牌的数字映射
    • 扑克牌的数字从 3A2 不允许出现在顺子中。
    • 我们需要将输入的字符串转换为一组整数,并为 J, Q, K, A 等字符指定具体的值:J -> 11, Q -> 12, K -> 13, A -> 14。
  2. 统计牌的数量
    • 用一个数组 freq 来统计每个数字的出现次数。数组的索引对应扑克牌的数字(3-14),我们将其映射到一个数组中。
  3. 寻找顺子
    • 顺子必须是至少5张连续的牌。我们使用双指针方法来查找连续的非零牌,并检查其是否满足顺子的要求(至少5张连续的牌)。
  4. 输出结果
    • 找到符合要求的顺子后,按从小到大的顺序输出每一个顺子。如果没有顺子,输出 "No"。

解题步骤:

  1. 初始化一个数组 freq,用来记录扑克牌的数量,数组长度为15(包括3到14,排除2)。
  2. 遍历输入的牌,根据每张牌的字符映射到 freq 数组中的对应位置。
  3. 使用双指针方法寻找符合顺子规则的牌型。
  4. 如果找到顺子,输出顺子;如果没有找到任何顺子,输出 "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++笔试真题题解 文章被收录于专栏

笔试真题题解

全部评论
mark一下
点赞 回复 分享
发布于 04-22 14:13 湖北

相关推荐

评论
3
3
分享

创作者周榜

更多
牛客网
牛客企业服务