题目描述
给出4个1-10的数字,通过加减乘除运算,得到数字为24就算胜利,除法指实数除法运算,运算符仅允许出现在两个数字之间,本题对数字选取顺序无要求,但每个数字仅允许使用一次,且需考虑括号运算
此题允许数字重复,如3 3 4 4为合法输入,此输入一共有两个3,但是每个数字只允许使用一次,则运算过程中两个3都被选取并进行对应的计算操作。
输入描述
读入4个[1,10]的整数,数字允许重复,测试用例保证无异常数字。
输出描述
对于每组案例,输出一行表示能否得到24点,能输出true,不能输出false
代码&思路
思路
因为只有4个数字,判断当前已经载入几个数字和运算符,再做下一步操作的代码是可能的。本人的想法是用递归的办法把所有可能的算式列举出来,判断其中是否有等于24的,若有则用列表记录。
- 载入第1个数字,这个时候没有任何限制
- 载入第2个数字和第1个运算符,这时候有两个限制:4个数字不能重复使用,可以用count函数判断;如果第2个数字是0,则第一个运算符不能载入/
- 载入第3个数字和第2个运算符,以及载入第4个数字和第3个运算符的思路同上
- 由于题目还需要我们考虑括号运算,不妨在载入第1个数字以后的所有操作后面同时递归一次,该算式加上括号的情况,这样就把所有可能的括号运算也考虑了
- 最后判断记录24点算式的列表长度是否非0,即可得到答案
代码
res=[]
sign=['+','-','*','/'] # 运算符
number=list(input().split()) # 记录数字
# 递归 算出所有可能的选择 判断其中是否有方案能得到24点
def f(S):
# 所有运算符和数字都已经载入 结束当前递归
if len(S)==7:
tmp=''.join(S)
if eval(tmp)==24:
res.append(S)
return 'finish'
# 载入第一个数字
if len(S)==0:
for x in number:
tmp=S[:]
tmp.append(x)
f(tmp)
# 载入第2个数字和第1个运算符
# 若第2个数字为0,则不能载入/ 且4个数字不能重复使用
if len(S)==1:
for x in number:
if S.count(x)<number.count(x):
for symbol in sign:
if x=='0' and symbol=='/':
pass
else:
tmp=S[:]
tmp.append(symbol)
tmp.append(x)
f(tmp) # 无括号的情形
tmp.append(')')
tmp.insert(0,'(')
f(tmp) # 将当前算式括起来,即为有括号的情形
# 载入第3个数字和第2个字符
if len(S)==3:
for x in number:
if S.count(x)<number.count(x):
for symbol in sign:
if x=='0' and symbol=='/':
pass
else:
tmp=S[:]
tmp.append(symbol)
tmp.append(x)
f(tmp) # 无括号的情形
tmp.append(')')
tmp.insert(0,'(')
f(tmp) # 将当前算式括起来,即为有括号的情形
# 载入第4个字符和第三个运算符 无需考虑括号
if len(S)==5:
for x in number:
if S.count(x)<number.count(x):
for symbol in sign:
if x=='0' and symbol=='/':
pass
else:
tmp=S[:]
tmp.append(symbol)
tmp.append(x)
f(tmp) # 无括号的情形
f([])
if len(res)>0:
print('true')
else:
print('false')