python实现24点变通题思路详解

python实现24点变通题思路详解

24点的变通题

题: 已知现在有四个数字a,b,c,d,在每两个数字中间插入一个计算符号组成计算式,寻找一种组合使得计算式结果等于24

输入:[a,b,c,d],如[4,7,8,2]
输出:若有解则输出true,若无解则返回false

范例:输入[4,7,8,2],可构成 4 * 7 - 8 / 2 = 24,有解,返回true

其他约束:
____计算符号可取:+ - * /,不考虑括号
____数字取值范围:[1,10]

题目分析

这道题看上去是24点游戏的变体,通过在每两个数字中间插入符号来组成计算式。我们所要做的是,寻找可行解。由于数字的顺序固定,且不存在括号,所以有4*3=12种可能出现的情况,穷举法想必是比较合适的。

思路

先用穷举法得到可能的计算式,然后对计算式进行验证,直至找到一个可行解。在验证时,由于存在乘除运算,计算时需考虑计算符号优先级。可以将有乘除号的部分视作一个整体计算。
python在处理字符串时,有split方法可以很方便地对字符串做分解。所以,我将计算式转为字符串,再用split方法将计算式分解为多个相加(减)的项。单独计算每个项的值。由于每个项中只有乘法和除法,所以从左到右计算即可。将每个项相加(减),就可以得到整个式子的值。
最后,验证ans是否为24,若找到,即可停止搜索

算法实现

# 单项计算
def pcal(p):
    # 此时计算式中只存在乘除计算,乘法被表达为*,除法表达为*/
    # 根据*可以将数字再分开
    pp = p.split("*")
    ans = 1
    for i in pp:
        if i[0] == "/":
            # 前面带有/,表示此步为除法
            ans = ans / int(i[1:(len(i))])
        else:
            # 不带/号,表示此步为乘法
            ans = ans * int(i)
    # 返回分块的计算结果
    return ans


text = input().split(",")
a = text[0][1:(len(text[0]))]
b = text[1]
c = text[2]
d = text[3][0:(len(text[3])-1)]

# a (x) b (y) c (z) d
# + - * /

find = False

# 将-写成+-,/写成*/有助于后面的分解
for x in ["+","+-","*","*/"]:
    if find: break
    for y in ["+","+-","*","*/"]:
        if find: break
        for z in ["+","+-","*","*/"]:
            if find: break
            # 转化为字符串计算式
            caltext = a + x + b + y + c + z + d
            parts = caltext.split("+")
            ans = 0
            # 一步分解(将式子分解为相加的多项)
            for p in parts:
                if p[0] == "-":
                    # 分块计算(计算每一项),带有-号,在结果上减掉
                    ans = ans - pcal(p[1:(len(p))])
                else:
                    # 分块计算(计算每一项),带有+号,在结果上加上
                    ans = ans + pcal(p)
            if ans == 24:
                find = True
                # 还原可读式,打印输出
                orltext = caltext.replace("+-","-")
                orltext = orltext.replace("*/","/")
                print(orltext)

if find:
    print("true")
else:
    print("false")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值