【Python代码】给定正整数,在+-*/的情况下,算法实现24点游戏,计算所有的可能

本文深入探讨了一道经典的计算24点问题,通过Python实现,详细解释了递归遍历所有可能组合的方法,以及如何优化计算过程避免重复。代码示例清晰,适合算法初学者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面回顾一下前两天面试过程中,做的一到笔试题:
题目:计算24 点,输入4 个整数,如何计算得到24,输出所有可能的计算方式; 若不能计算得到则输出None。

解题思路:由于不考虑顺序, 括号的位置可以认为有两种[(a, b, c) d ]; [(a,b), (c,d)],然后递归地遍历所有的情况。里面有两个小点:
(1) a+b和b+a的情况一样,可以去掉一部分的计算
(2) 主函数中考虑到浮点计算,中间有一个判断。
代码如下:

#!/usr/bin/python
from __future__ import division
#Author: Marlin
#Time: 2018-10-15

def permutation(items, n=None):
    if n is None:
        n = len(items)
    for i in range(len(items)):
        v = items[i:i + 1]
        if n == 1:
            yield v
        else:
            rest = items[:i] + items[i + 1:]
            for p in permutation(rest, n - 1):
                yield v + p


def F(a, b):
    arr = []
    for i in a:
        for j in b:
            arr.append("(" + i + "+" + j + ")")
            arr.append("(" + i + "-" + j + ")")
            arr.append("(" + j + "-" + i + ")")
            arr.append("(" + i + "*" + j + ")")

            eval(j) != 0 and arr.append("(" + i + "/" + j + ")")
            eval(i) != 0 and arr.append("(" + j + "/" + i + ")")
    return arr


def main(arr):
    vaild_exprs = []
    for lst in permutation(arr):
        a_expr = F(F(F([lst[0]], [lst[1]]), [lst[2]]), [lst[3]])

        b_expr = F(F([lst[0]], [lst[1]]), F([lst[2]], [lst[3]]))
        all_expr = a_expr + b_expr
        for expr in all_expr:
            if abs(eval(expr) - 24) < 0.0001:
                vaild_exprs.append(expr)
                print(expr)
    print('None' if len(vaild_exprs) == 0 else 'Total:{}'.format(len(vaild_exprs)))


if __name__ == '__main__':
    # sample = [3, -12, 3, 0]
    # sample = [3, -12, 7, 1]
    sample = [1, 7, 3, 8]
    arr = [str(i) if i >= 0 else '('+str(i)+')' for i in sample ]
    main(arr)

代码仅供内部交流

这个问题是一个经典的数学和编程挑战,称为“四则运最小化”。为了找到一个算法,我们可以使用贪心策略和回溯法。首先,我们需要创建一个函数,该函数会尝试将目标数字`m`分解成一系列操作,每次迭代都尽可能选择最大的数进行乘法操作,因为乘法通常需要更多的运次数。如果当前乘积大于目标值,我们就尝试减法;如果小于目标值,就加法。同时,我们跟踪剩余的数以及可用的运次数。 以下是算法的伪代码: ```python function find_min_operations(m, numbers, operators, remaining_nums, ops_used): if m == 0 and remaining_nums == []: # 如果达到目标,返回使用的运次数 return ops_used best_solution = float('inf') # 初始化最优解为无穷大 for i in range(len(numbers)): num = numbers[i] new_remaining_nums = remaining_nums.copy() # 创建新的剩余数列表 new_ops_used = ops_used + 1 # 操作数增加 # 尝试加法 if op := '+': new_m = m - num new_remaining_nums.remove(num) # 尝试减法 elif op := '-': if num <= m: new_m = m - num new_remaining_nums.remove(num) else: continue # 如果num大于m,直接跳过 # 尝试乘法 elif op := '*': new_remaining_nums.remove(num) # 乘法后再使用这个数 if len(new_remaining_nums) >= 1: new_m = m * (numbers[new_remaining_nums[0]] / num) # 更新新目标 new_remaining_nums.pop(0) # 同理,尝试除法 result = find_min_operations(new_m, new_remaining_nums, operators, [], new_ops_used) if result != float('inf'): # 如果找到了解决方案 best_solution = min(best_solution, result) if best_solution == float('inf'): return None # 如果找到方案,则返回None return best_solution # 调用函数,输入初始值m和所有数字 min_operations = find_min_operations(m, [1, 2, 3, 4, 5, 6, 7, 8, 9], ['+', '-', '*', '/'], [1, 2, 3, 4, 5, 6, 7, 8, 9], 0) ``` 请注意,这个算法保证一定能找到全局最优解,尤其是当目标值很大合复杂时。实际应用中,可能需要使用更复杂的搜索算法或者启发式方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值