华为笔试训练题-24点运算(python3处理)

华为机试完整题库链接: https://www.nowcoder.com/ta/huawei
本题链接: https://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d
华为笔试训练题-24点运算(python3处理)

解题思路:
要注意的点: 1-13每个数字都有可能出现4次,所以用穷举法,可能性太多,难以穷举完全, 因为找不到完整的规律,所以考虑直接使用暴力搜索;
即: 1-13中 使用4层嵌套循环,第1层 第1个数字从1-13开始遍历,第2层,即第2个数字从1-13开始遍历,第3,第4层同样,这样就把所有有序排列组合都展示出来了;
第二步就是数字间的(+ - * / )组合运算, 四个数字,中间需要3个运算符, 即从4个中取3个的有序排列组合,比如 +-* , +++,---;等等同样使用3层遍历;

工具介绍:
python中封装了专门排列组合的库 itertools,具体了解参考链接: https://docs.python.org/zh-cn/3/library/itertools.html
上述提到,所有的排列组合,重复的考虑使用 itertools.product 笛卡尔积,不重复的使用 itertools.permutations
简单介绍下它们的使用:

for i in (x for x in product('ABCD', repeat=2)):
    print(i)
# 输出结果是: AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
# 即product中第一个参数是可迭代器,第二个参数的值是组合的长度

for j in (x for x in permutations('ABCD', repeat=2)):
    print(j)
# 输出结果是: AB AC AD BA BC BD CA CB CD DA DB DC

通过上述我们可以把所有数字排列组合用运算符字符串拼接成一个字符串,但最终我们要的是数字间的运算结果,所以我们需要把包含运算符的字符串转化为数字运算,
这里就需要用到python 的eval 函数了,简单介绍下使用:

x = 7
y= eval( '3 * x' )
print(y) # 输出21

开始解题

import itertools

def fun(li):
    # 字符串切分后的列表, 如果包含大小王则直接返回 ERROR
    if li.__contains__('joker') or li.__contains__('JOKER'):
        print('ERROR')
        return
    # 扑克牌中 JQKA 和对应数字的替换,便于后续数字操作,即下数d,注意后续满足条件的输出要重新替换回JQKA,属于原格式也要保留,即li
    m={'J':'11','Q':'12','K':'13','A':'1'}
    d=[]
    for i in li:
        if i in m:
            d.append(m[i])
        else:
            d.append(i)
    c = ['+','-','*','/']
    # x 和 c  组合 表示运算符的所有排列组合(4取3)
    for i in (x for x in itertools.product( range(4),repeat=3)):
      # j 和 d  组合 表示输入的长度为4的字符串 打散后所有有序的排列组合
      for j in itertools.permutations(range(4),4):
          # 替换成数字后的所有数字和运算符字符串拼接的完整字符串组合
          # t1 = d[j[0]] + c[i[0]] + d[j[1]] + c[i[1]] + d[j[2]] + c[i[2]] + d[j[3]]
          # 这里() 需要加,不加在牛客网中代码通过率始终只有50% ,这里有点坑;
          t1 = '((' + d[j[0]] + c[i[0]] + d[j[1]]+ ')' + c[i[1]] + d[j[2]]+ ')' + c[i[2]] + d[j[3]]
          # 原生的拼接组合
          t2 = li[j[0]] + c[i[0]] + li[j[1]] + c[i[1]] + li[j[2]] + c[i[2]] + li[j[3]]
          if eval(t1) == 24:
              print(t2)
              return
    print('NONE')

if __name__ == '__main__':
    while True:
        try:
            s = input()
            fun(s.strip().split())
        except:
            break

华为笔试训练题-24点运算(python3处理)

本文解题参考链接:https://www.nowcoder.com/questionTerminal/7e124483271e4c979a82eb2956544f9d

上一篇:itertools---排列组合


下一篇:python基础教程:用Python秒算24点实现及原理详解