一、主要思路
- 拒绝多个 for 循环,本题只有 4 张牌,但如果是 8、16、32、64、128、256、1024 张牌,难道还写 for 循环吗?
- 四张牌计算得 24,可以拆解为 3 张牌计算结果和第四章进行计算的 24。可以采用递归。
- 可以使用字典或列表的 index 来转换牌的面值和实际的大小
二、简化问题
2.1 思路
首先可以计算简单的场景,假设四张牌按顺序是固定的,看能否得出 24。
- 首先将牌面切换成牌的实际大小组成新的列表,方便比较
- 每次取前面的 2 张牌,并且记住顺序,分别进行 + - * // 运算,然后将其值插入剩余的牌的开头组成新的牌组(该牌组中的牌的值,可能会超出正常牌组所有可能出现的值),迭代此过程
- 迭代的终点:当牌组中牌的数量为 1 时,该张牌的值即为最终的计算结果,若等于 24,本次计算过程即为最终答案。
- 若存在正确的计算结果,则将每次计算的过程添加到一个专门用于存储计算步骤的列表中,该列表即为最后需要的答案
2.2 代码
cards = ['0', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'joker', 'JOKER']
class A:
def __init__(self, nums):
self.nums = nums
self.rst = []
def __func(self, nums):
# print(nums)
if len(nums) == 1:
if nums[0] == 24:
return True
else:
return False
cur1 = nums.pop(0)
cur2 = nums.pop(0)
if self.__func([cur1 + cur2] + nums):
self.rst.insert(0, cur2)
self.rst.insert(0, '+')
return True
elif self.__func([cur1 - cur2] + nums):
self.rst.insert(0, cur2)
self.rst.insert(0, '-')
return True
elif self.__func([cur1 * cur2] + nums):
self.rst.insert(0, cur2)
self.rst.insert(0, '*')
return True
elif self.__func([cur1 // cur2] + nums):
self.rst.insert(0, cur2)
self.rst.insert(0, '/')
return True
return False
def func(self):
self.__func(self.nums[:])
if self.rst:
self.rst.insert(0, self.nums[0])
s = input()
if 'joker' in s or 'JOKER' in s:
print('ERROR')
else:
nums = [cards.index(_) for _ in s.split()]
a = A(nums=nums)
a.func()
if a.rst:
print("".join(cards[_] if isinstance(_, int) else _ for _ in a.rst))
else:
print('NONE')
三、最终解法
3.1 思路
- 在前目的步骤中,我们每次取牌组中的牌时,可以不按顺序取,则每次第一张牌可以取的方式为 len(牌组) 个,第二张牌可以取的方式为 len(剔除第一张牌后的新牌组) 个
- 首先随机取出第一张牌,然后剩余的牌组成新的牌组,使用第一张牌和剩余牌组进行迭代,每次迭代只需要循环取第二张牌然后和第一张牌进行计算即可
3.2 代码
cards = ['0', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'joker', 'JOKER']
class A:
def __init__(self, nums):
self.nums = nums
self.rst = []
def __func(self, cur1, nums):
# print(nums)
if len(nums) == 0:
if cur1 == 24:
return True
else:
return False
for i in range(len(nums)):
nums2 = nums[:]
cur2 = nums2.pop(i)
if self.__func(cur1 + cur2, nums2):
self.rst.insert(0, cur2)
self.rst.insert(0, '+')
return True
elif self.__func(cur1 - cur2, nums2):
self.rst.insert(0, cur2)
self.rst.insert(0, '-')
return True
elif self.__func(cur1 * cur2, nums2):
self.rst.insert(0, cur2)
self.rst.insert(0, '*')
return True
elif cur2 != 0 and self.__func(cur1 // cur2, nums2):
self.rst.insert(0, cur2)
self.rst.insert(0, '/')
return True
return False
def func(self):
for i in range(len(self.nums)):
nums = self.nums[:]
cur1 = nums.pop(i)
if self.__func(cur1, nums):
self.rst.insert(0, cur1)
break
s = input()
if 'joker' in s or 'JOKER' in s:
print('ERROR')
else:
nums = [cards.index(_) for _ in s.split()]
a = A(nums=nums)
a.func()
if a.rst:
# print(a.rst)
print("".join(cards[_] if isinstance(_, int) else _ for _ in a.rst))
else:
print('NONE')