问题描述
24点游戏是一个非常有意思的游戏,很流行,玩法很简单:给你4张牌,每张牌上有数字(其中A代表1,J代表11,Q代表12,K代表13),你可以利用数学中的加、减、乘、除以及括号想办法得到24,例如:
((A*K)-J)*Q等价于((1*13)-11)*12=24
加减乘不用多说了,但除法必须满足能整除才能除!这样有一些是得不到24点的,所以这里只要求求出不超过24的最大值。
输入格式
输入第一行N(1<=N<=5)表示有N组测试数据。每组测试数据输入4行,每行一个整数(1到13)表示牌值。
输出格式
每组测试数据输出一个整数,表示所能得到的最大的不超过24的值。
样例输入
3
3
3
3
3
1
1
1
1
12
5
13
1
样例输出
24
4
21
初步思路:
初步思路就是没有思路,根据网上大佬答案,找到大体的解决方法:与”粘木棍“逻辑相似,取任意两张牌,进行加减乘除四种情况的运算,得到新的牌取代参与运算的牌,不断搜索下去,直到数组长度为1,最后result中取最小的即可,同”粘木棍“,二维递归,且对nums[i]进行更改,乐了,这跟粘木棍一样一样的,直接照写,不出意外,0蛋:
n=int(input())
li1=[[]for _ in range(n)]
result=[[] for i in range(n)]
class Solution:
def __init__(self):
self.result=[]
def solve(self,N,li):
li.sort()
self.flag=0
self.backtracking(N,li)
return self.result
def backtracking(self,N,li):
print(li,N)
if self.flag==1:
return
if N==1:
if li[0]>24:
return
elif li[0]==24:
self.result=[24]
self.flag=1
return
else:
self.result.append(li[0])
return
for i in range(N):
for j in range(i+1,N):
a=li[i]
b=li[j]
li[i]=a+b
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
#
li[i]=a*b
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
#
li[i]=a-b
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
#
li[i]=b-a
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
#
if a!=0 and b%a==0:
li[i]=b/a
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
#
if b!=0 and a%b==0:
li[i]=a/b
li[j],li[N-1]=li[N-1],li[j]
self.backtracking(N-1,li)
li[j],li[N-1]=li[N-1],li[j]
li[i]=a
for i in range(n):
s=Solution()
result=[]
result=s.solve(4,li1[i])
print(max(result))
进阶思路:
这里不同于”粘木棍“的是,本题为多重递归,因为有加减乘除4种情况,故不能采用”粘木棍“的”多于元素与末尾元素调换位置“的模式,因为回溯只有一次,多次递归迟早会搜索到被调换到末尾的无用元素,故这里采用nums[j]=nums[N-1]的方法,具体解释:
n数字,其中两个数字相处理后会导致
j位置的数字被更新而i位置的数字无效,
此时将最后一个数调到i位置
这样有效数字正好变成了前n-1个数字
比如1 2 3 4
计算1+2后
变成1 3 3 4
调整后变成4 3 3 4
有效数字3 3 4 就正好到了前三个位置,必须保证把有效的3个数字移到最前面。又或者换句话说最后一个数即nums[n-1]一定是有效的,但当有效数字的个数减少时,最后一个数就必须要提前,即赋值给i位置
然后轻松(个屁)AC:
n=int(input())
li1=[[]for _ in range(n)]
result=[[] for i in range(n)]
for i in range(n):
for j in range(4):
li1[i].append(int(input()))
class Solution:
def __init__(self):
self.result=[]
def solve(self,N,li):
li.sort()
self.flag=0
self.backtracking(N,li)
return self.result
def backtracking(self,N,li):
if self.flag==1:
return
if N==1:
if li[0]>24:
return
elif li[0]==24:
self.result=[24]
self.flag=1
return
else:
self.result.append(li[0])
return
for i in range(N):
for j in range(i+1,N):
a=li[i]
b=li[j]
li[i]=a+b
li[j]=li[N-1]
self.backtracking(N-1,li)
#
li[i]=a*b
li[j]=li[N-1]
self.backtracking(N-1,li)
#
li[i]=a-b
li[j]=li[N-1]
self.backtracking(N-1,li)
#
li[i]=b-a
li[j]=li[N-1]
self.backtracking(N-1,li)
#
if a!=0 and b%a==0:
li[i]=b/a
li[j]=li[N-1]
self.backtracking(N-1,li)
#
if b!=0 and a%b==0:
li[i]=a/b
li[j]=li[N-1]
self.backtracking(N-1,li)
li[i]=a
li[j]=b
for i in range(n):
s=Solution()
result=[]
result=s.solve(4,li1[i])
print(max(result))