Skip to content

HJ89 24点运算 ​

本节目标:理解“HJ89 24点运算”的核心思路,并能把它用于实际开发或面试表达。 较难 通过率:22.02% 时间限制:1秒 空间限制:32M 知识点==字符串====模拟====穷举== 描述 计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王: 3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER 本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。 详细说明: 1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1; 2.牌面2~10对应的权值为2~10, J、Q、K、A权值分别为为11、12、13、1; 3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算; 4.输出的算式格式为4张牌通过+-/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确; 5.输出算式的运算顺序从左至右,不包含括号,如1+2+34的结果为24,2 A 9 A不能变为(2+1)(9-1)=24 6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。 7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0

数据范围:一行由4张牌组成的字符串 输入描述: 输入4张牌为字符串形式,以一个空格隔开,首尾无空格; 输出描述: 输出怎么运算得到24,如果无法得出24,则输出“NONE”表示无解,如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算; 示例1 输入: A A A A ==复制== 输出: NONE ==复制== 说明: 不能实现 示例2 输入: 4 2 K A ==复制== 输出: K-A4/2 ==复制== 说明: A+K2-4也是一种答案,输出任意一种即可 示例3 输入: B 5 joker 4 ==复制== 输出: ERROR ==复制== 说明: 存在joker,输出ERROR 示例4 输入: K Q 6 K ==复制== 输出: NONE ==复制== 说明: 按一般的计算规则来看,K+K-(Q/6)=24 或 K-((Q/6)-K)=24,但是因为这个题目的运算不许有括号,所以去掉括号后变为 K+K-Q/6=26-Q/6=14/6=2 或 K-Q/6-K=1/6-K=0-K=-13,其它情况也不能运算出24点,故不存在,输出NONE

第一部分:定义牌的数值 ​

记录了每张牌对应的分数,A就是1分,2就是2分,以此类推,K是13分,小王和大王是特殊的,我们在这个游戏里不用它们。 ​

card_values = { "A": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10, "J": 11, "Q": 12, "K": 13, "joker": 0, "JOKER": 0, }

第二部分:生成所有可能的牌的排列 ​

帮我们找到所有不同的牌的排列方式,比如你有四张牌,它会告诉你所有不同的排列顺序。 ​

def generate_permutations(lst): if len(lst) == 0: return [[]] # 如果没有牌,就没有排列方式。 perms = [] # 这是我们用来保存所有排列的盒子。 for i in range(len(lst)): # 对于牌堆里的每一张牌, m = lst[i] # 我们拿出这张牌, remLst = lst[:i] + lst[i + 1:] # 然后把剩下的牌留下。 for p in generate_permutations(remLst): # 对剩下的牌进行同样的操作,找出所有排列。 perms.append([m] + p) # 把当前拿出的牌放到每一种排列的前面。 return perms # 最后,我们得到了所有的排列方式!

第三部分:生成运算符的所有组合 ​

现在我们来生成所有可能的运算符组合,就像我们有多种方式组合加减乘除一样。 ​

def generate_operator_combinations(operators, length): if length == 1: return [[o] for o in operators] # 如果只需要一个运算符,那就直接返回所有可能的运算符。 combinations = [] # 这是我们用来保存所有组合的盒子。 for o in operators: # 对于每一个可能的运算符, for c in generate_operator_combinations( operators, length - 1 ): # 我们再次调用自己,找出剩下的组合。 combinations.append([o] + c) # 把当前的运算符添加到每一种组合的前面。 return combinations # 最后,我们得到了所有的运算符组合!

第四部分:计算表达式的值 ​

这个函数可以计算给定牌和运算符的表达式值。 ​

def calculate_expression(cards, operators): try: result = card_values[cards[0]] # 我们从第一张牌的分数开始。 for i, operator in enumerate(operators): # 然后,对于每一个运算符, if operator == "+": # 如果是加号, result += card_values[cards[i + 1]] # 我们就加上下一张牌的分数。 elif operator == "-": # 同理,对于减号、乘号、除号,我们做相应的计算。 result -= card_values[cards[i + 1]] elif operator == "*": result *= card_values[cards[i + 1]] elif operator == "/": result = result / card_values[cards[i + 1]] return result # 最后,我们得到了这个表达式的结果! except ZeroDivisionError: # 如果我们不小心除以0了,就返回None,因为这不是一个有效的操作。 return None

第五部分:寻找24点的解决方案 ​

这个函数是我们的主要任务,要找出24点的方案。 ​

def find_24_solution(cards): if any( card in ["joker", "JOKER"] for card in cards ): # 如果有大小王,就直接返回“ERROR”,因为我们不能用它们。 return "ERROR" permutations = generate_permutations(cards) # 生成所有牌的排列。 operator_combinations = generate_operator_combinations( ["+", "-", "*", "/"], 3 ) # 生成所有运算符的组合。 for perm in permutations: # 对于每一种牌的排列, for operators in operator_combinations: # 和每一种运算符的组合, if calculate_expression(perm, operators) == 24: # 如果这样算出来是24, return "".join( [f"{perm[i]}{operators[i]}" for i in range(3)] + [perm[3]] ) # 就把这个方案返回出去。 return "NONE" # 如果找遍了所有的组合都没有24点,就返回“NONE”,意味着没有解决方案。

最后,我们从用户那里得到四张牌,然后尝试找出24点的方案。 ​

cards = input().split() print(find_24_solution(cards))

values = [card_values.get(card, int(card)) for card in cards]

  • card_values:这是一个字典,它映射了每个特殊牌面值("J"、"Q"、"K"、"A")到它们各自的数值(11、12、13、1)。这个映射用于快速查找特殊牌面值的数值。

  • for card in cards:这部分是列表推导式的循环部分,它遍历输入列表cards中的每一张牌。每次循环时,变量card会被赋值为列表中的一张牌面值。

  • card_values.get(card, int(card)):对于每张牌面值card,这个表达式尝试从card_values字典中获取card对应的数值。字典的.get()方法接受两个参数:第一个参数是要查找的键(在这里是牌面值card),第二个参数是一个默认值,当字典中找不到指定的键时返回这个默认值。在这个例子中,如果card是一个特殊牌面值(如"J"),.get()方法会返回映射中定义的数值(如11)。如果card不是一个特殊牌面值(即它是一个数字字符串,如"2"、"3"等),.get()方法会尝试将这个字符串转换为整数int(card),并返回这个整数作为数值。

本站总访问 — 次