华为OJ24点问题:穷举法暴力求解

24点运算

http://www.nowcoder.com/questionTerminal/7e124483271e4c979a82eb2956544f9d

思路:
由于四则运算组合的可能性很多,而且不存在子问题模板化适配,所以 递归、分治、动态规划的方式不行,不要遇见难一点的题就条件反射到这些方法上。
本题是必须穷举的,也就是暴力法。
我们先评估下暴力求解时的问题规模:4个数字,3个运算符。由于不允许带括号,而且数字先后顺序不固定,所以对于数字位来说肯定是排序问题,一共4*3*2*1 = 24种排列,
另外对于运算符,每个位置都有4种取值可能,故是4^3 = 64种,所以整体的问题规模是 24*64 = 1536个计算组合。也就是给定4个数字,最极端的情况也就1536次四则运算,这个问题规模2s内完成。
这里用python的eval、笛卡尔积函数product跟生成排序序列的permutation函数,相比cpp/java 缩减代码行数。

运行时间:51ms            占用内存:3680k
import sys
import itertools

def calc_24points(data):
    map2={'J':'11','Q':'12','K':'13','A':'1'}
    new_data=[]
    for d in data:
        if d in map2:
            new_data.append(map2[d])
        else:
            new_data.append(d)

    map1={'0':'+','1':'-','2':'*','3':'/'}   
    for o in (''.join(x) for x in itertools.product(map(str,range(4)), repeat=3)):
        for i in itertools.permutations(range(4),4):
            temp1='(('+new_data[i[0]]+map1[o[0]]+new_data[i[1]]+')'+map1[o[1]]+new_data[i[2]]+')'+map1[o[2]]+new_data[i[3]]
            temp2=data[i[0]]+map1[o[0]]+data[i[1]]+map1[o[1]]+data[i[2]]+map1[o[2]]+data[i[3]]
            if ('joker' in temp1)&nbs***bsp;('JOKER' in temp1):
                print('ERROR')
                return
            elif eval(temp1)==24:
                    print(temp2)
                    return                 
    print('NONE')

for line in sys.stdin:
    data = list(map(str, line.strip().split()))
    calc_24points(data)


全部评论
按规则,不能递归,但是测试用例不全面,所有用例都可以递归!晕
1 回复 分享
发布于 2022-07-04 17:38
递归是可以的
1 回复 分享
发布于 2023-11-05 15:11 江苏
有没有人可以帮忙看一下,我这段代码为啥只能通过50%? import itertools Dic1={'A':'1','J':'11','Q':'12','K':'13'} cal={'0':'+','1':'-','2':'*','3':'/'} while True: try: mylist=list(map(str,input().split())) mylist2=[] if ('joker' in mylist) or ('JOKER' in mylist): print('ERROR') else: for i in mylist: if i in Dic1.keys: mylist2.append(mylist[Dic1[i]]) else: mylist2.append(i) for x in (''.join(m) for m in itertools.product(map(str,range(4)),repeat=3)): for j in itertools.permutations(range(4),4): temp1='(('+mylist2[j[0]]+cal[x[0]]+mylist2[j[1]]+')'+cal[x[1]]+mylist2[j[2]]+')'+cal[x[2]]+mylist2[j[3]] temp2=mylist2[j[0]]+cal[x[0]]+mylist2[j[1]]+cal[x[1]]+mylist2[j[2]]+cal[x[2]]+mylist2[j[3]] if eval(temp1)==24: print(temp2) print('NONE') except: break
点赞 回复 分享
发布于 2020-08-14 21:58
刚刚看懂自己写了一遍,这里外层operation用product是因为操作符是可以重复的即4+2+3+1可以三个都是+,但是permutation是不会重复的遍历,对应数字每个只出现一次
点赞 回复 分享
发布于 2021-10-01 23:30
递归咋不行了
点赞 回复 分享
发布于 2022-04-21 13:14
为啥 temp1 要拼接 括号,题意不让用括号
点赞 回复 分享
发布于 2022-09-11 13:41 河南
如果题目要求包括括号运算,那这个方法还可以照用吗?这是我唯一能看懂的方法,dfs和递归那些都看不懂。。。
点赞 回复 分享
发布于 11-21 21:41 江苏

相关推荐

点赞 评论 收藏
分享
11-23 22:07
同济大学 Java
贺兰星辰:你这简历完全可以缩到一页,校园工作、自我评价完全可以删了,没人看的;个人技能可以写多点。
点赞 评论 收藏
分享
评论
33
5
分享
牛客网
牛客企业服务