【华为OD-E卷 – 德州扑克 100分(python、java、c++、js、c)】

【华为OD-E卷 – 德州扑克 100分(python、java、c++、js、c)】

题目

五张牌,每张牌由牌大小和花色组成,牌大小2~10、J、Q、K、A,牌花色为红桃、黑桃、梅花、方块四种花色之一。
判断牌型:
牌型1,同花顺:同一花色的顺子,如红桃2红桃3红桃4红桃5红桃6。 牌型2,四条:四张相同数字 + 单张,如红桃A黑桃A梅花A方块A + 黑桃K。 牌型3,葫芦:三张相同数字 + 一对,如红桃5黑桃5梅花5 + 方块9梅花9。 牌型4,同花:同一花色,如方块3方块7方块10方块J方块Q。 牌型5,顺子:花色不一样的顺子,如红桃2黑桃3红桃4红桃5方块6。 牌型6,三条:三张相同+两张单。
说明:
(1)五张牌里不会出现牌大小和花色完全相同的牌。 (2)编号小的牌型较大,如同花顺比四条大,依次类推。 (3)包含A的合法的顺子只有10 J Q K A和A 2 3 4 5;类似K A 2 3 4的序列不认为是顺子

输入描述

  • 输入由5行组成,每行为一张牌大小和花色,牌大小为2~10、J、Q、K、A,花色分别用字符H、S、C、D表示红桃、黑桃、梅花、方块
  • 输出描述

  • 输出牌型序号,5张牌符合多种牌型时,取最大的牌型序号输出
  • 用例

    用例一:
    输入:
    4 H
    5 S
    6 C
    7 D
    8 D
    
    输出:
    5
    
    用例二:
    输入:
    9 S
    5 S
    6 S
    7 S
    8 S
    
    输出:
    1
    

    python解法

  • 解题思路:
  • 这道题目要求判断给定的五张牌组合是什么类型的牌型,并返回相应的数字编码。我们要根据标准的扑克牌规则来判断牌型。常见的牌型包括顺子(Shunzi)、同花(Tonghua)、三条(Santiao)、葫芦(Hulu)、四条(Sitiao)等。
  • 解题的步骤如下:

    输入处理:

    我们需要读取五张牌的输入,每张牌由数字和花色组成。输入后将其转换成一个二维列表,方便后续处理。
    牌值转换:

    将牌的数字(包括 J, Q, K, A 等)转换成数值,以便进行大小比较。
    例如:J 转换为 11,Q 转换为 12,K 转换为 13,A 转换为 14。
    牌型判断:

    顺子(Shunzi):五张牌是连续的。
    同花(Tonghua):五张牌的花色相同。
    三条(Santiao):有三张相同的牌。
    葫芦(Hulu):有三张相同的牌和两张相同的牌。
    四条(Sitiao):有四张相同的牌。
    返回结果:

    根据判断的结果返回相应的牌型编号。例如:顺子同花返回 1,四条返回 2,葫芦返回 3,等等。

    # 获取五张牌的输入,输入格式:每行一个数字和花色,格式如 "3 H"
    arr = [input().split() for _ in range(5)]
    
    # 将牌面值转换为相应的数字值,方便后续比较
    def cards(num):
        if num == "J":
            return 11
        elif num == "Q":
            return 12
        elif num == "K":
            return 13
        elif num == "A":
            return 14
        else:
            return int(num)
    
    # 用于判断一组牌是否满足特定条件:
    # partCount:分成几组相同的牌
    # maxSameNumCount:每组最多相同的牌的数量
    def countNums(nums, partCount, maxSameNumCount):
        count = {}
    
        # 统计每种牌的数量
        for num in nums:
            if count.get(num) is None:
                count[num] = 0
            count[num] += 1
    
        # 判断是否有 partCount 种牌
        if len(count.keys()) != partCount:
            return False
    
        # 判断是否有 maxSameNumCount 个相同的牌
        return maxSameNumCount in count.values()
    
    # 判断是否是三条:有三张相同的牌
    def isSantiao(nums):
        return countNums(nums, 3, 3)
    
    # 判断是否是葫芦:有三张相同的牌和两张相同的牌
    def isHulu(nums):
        return countNums(nums, 2, 3)
    
    # 判断是否是四条:有四张相同的牌
    def isSitiao(nums):
        return countNums(nums, 2, 4)
    
    # 判断是否是同花:五张牌的花色相同
    def isTonghua(colors):
        return len(set(colors)) == 1
    
    # 判断是否是顺子:五张牌是连续的
    def isShunzi(nums):
        # 特殊情况:2345A,A作为1处理
        if "".join(nums) == "2345A":
            return True
    
        # 判断牌是否连续
        for i in range(1, len(nums)):
            if cards(nums[i - 1]) + 1 != cards(nums[i]):
                return False
        return True
    
    # 获取最终结果的函数
    def getResult():
        nums = []
        colors = []
    
        # 分离出牌面数字和花色
        for num, color in arr:
            nums.append(num)
            colors.append(color)
    
        # 对牌面值进行排序
        nums.sort(key=lambda x: cards(x))
    
        # 判断各种牌型的优先级
        if isShunzi(nums) and isTonghua(colors):  # 同花顺
            return 1
        elif isSitiao(nums):  # 四条
            return 2
        elif isHulu(nums):  # 葫芦
            return 3
        elif isTonghua(colors):  # 同花
            return 4
        elif isShunzi(nums):  # 顺子
            return 5
        elif isSantiao(nums):  # 三条
            return 6
        else:  # 其他情况
            return 0
    
    # 输出最终的牌型编号
    print(getResult())
    
    

    java解法

  • 解题思路
  • 这道题目要求根据输入的五张牌的点数和花色,判断其牌型并返回对应的编码。常见的牌型有同花顺、四条、葫芦、同花、顺子、三条等。
  • 解题步骤如下:

    输入获取:

    从输入中获取五张牌的点数(数字或字母)和花色。每张牌由一个数字(或字母表示的特殊牌,如 J, Q, K, A)和一个花色组成。
    牌值转换:

    将牌面上的字符(例如 J, Q, K, A)转换为数字值,方便后续排序和比较。
    J 转换为 11
    Q 转换为 12
    K 转换为 13
    A 转换为 14
    数字牌保持不变。
    分析牌型:

    同花顺(Straight Flush):五张牌是连续的,并且花色相同。
    四条(Four of a Kind):有四张相同的牌。
    葫芦(Full House):有三张相同的牌和两张相同的牌。
    同花(Flush):五张牌的花色相同。
    顺子(Straight):五张牌是连续的,不考虑花色。
    三条(Three of a Kind):有三张相同的牌。
    返回结果:

    根据不同的牌型,返回对应的数字编码。例如:同花顺返回 1,四条返回 2,葫芦返回 3,等等。如果不符合任何牌型,返回 0。

    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String[] nums = new String[5];   // 存储五张牌的点数
            String[] suits = new String[5];  // 存储五张牌的花色
    
            // 输入五张牌的点数和花色
            for (int i = 0; i < 5; i++) {
                nums[i] = sc.next();   // 输入点数
                suits[i] = sc.next();  // 输入花色
            }
    
            // 输出牌型结果
            System.out.println(getResult(nums, suits));
        }
    
        // 根据牌的点数和花色来判断牌型
        public static int getResult(String[] nums, String[] suits) {
            // 使用 TreeSet 存储牌的数值,保证自动排序
            TreeSet<Integer> values = new TreeSet<>();
            // 使用 Map 存储每个点数的出现次数
            Map<String, Integer> count = new HashMap<>();
            // 使用 Set 存储花色,判断是否同花
            Set<String> suitSet = new HashSet<>(Arrays.asList(suits));
    
            // 遍历所有牌,转换成数值并统计点数出现次数
            for (String num : nums) {
                int cardVal = cardValue(num);  // 将牌的点数转换为数值
                values.add(cardVal);           // 将牌数值加入到 TreeSet,自动排序
                count.put(num, count.getOrDefault(num, 0) + 1); // 更新点数出现次数
            }
    
            // 判断是否是同花:如果所有花色相同,则为同花
            boolean isFlush = suitSet.size() == 1;
            // 判断是否是顺子:如果牌的最大值与最小值差为 4 且牌数为 5,则为顺子
            // 或者特殊情况:A, 2, 3, 4, 5 也是顺子
            boolean isStraight = (values.last() - values.first() == 4 && values.size() == 5) || isLowAceStraight(values);
    
            // 牌型判断,从高到低:
            if (isStraight && isFlush) return 1; // 同花顺
            if (hasCount(count, 4)) return 2;    // 四条
            if (hasCount(count, 3) && hasCount(count, 2)) return 3;  // 葫芦
            if (isFlush) return 4;   // 同花
            if (isStraight) return 5;  // 顺子
            if (hasCount(count, 3)) return 6;   // 三条
            return 0;  // 没有符合的牌型
        }
    
        // 判断是否有某个点数出现 num 次
        private static boolean hasCount(Map<String, Integer> count, int num) {
            return count.containsValue(num);
        }
    
        // 判断是否是 A 2345 这种顺子(特殊情况)
        private static boolean isLowAceStraight(TreeSet<Integer> values) {
            return values.contains(14) && values.contains(2) && values.contains(3) && values.contains(4) && values.contains(5);
        }
    
        // 将牌的点数转换为数值
        private static int cardValue(String num) {
            switch (num) {
                case "J": return 11;  // Jack
                case "Q": return 12;  // Queen
                case "K": return 13;  // King
                case "A": return 14;  // Ace
                default: return Integer.parseInt(num);  // 其他牌是数字,直接返回数字
            }
        }
    }
    
    

    C++解法

  • 解题思路
  • 更新中
    

    C解法

  • 解题思路

  • 更新中
    

    JS解法

  • 解题思路

  • 更新中
    

    注意:

    如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
    解题不易,如对您有帮助,欢迎点赞/收藏

    作者:CodeClimb

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【华为OD-E卷 – 德州扑克 100分(python、java、c++、js、c)】

    发表回复