蓝桥杯-24点游戏

问题描述

  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))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值