蓝桥杯算式问题(全排列)

1. 问题描述:

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。看这个算式:☆☆☆ + ☆☆☆ = ☆☆☆,如果每个五角星代表 1 ~ 9 的不同的数字。这个算式有多少种可能的正确填写方法?
173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675

以上都是正确的填写法!注意: 111 + 222 = 333是错误的填写法! 因为每个数字必须是不同的! 也就是说:11~ 9中的所有数字,每个必须出现且仅出现一次!
注意:不包括数字 “0”“0”!
注意: 满足加法交换率的式子算两种不同的答案。 所以答案肯定是个偶数!
运行限制
最大运行时间:1s
最大运行内存: 128M
来源:https://www.lanqiao.cn/problems/731/learning/

2. 思路分析:

① 分析题目可以知道我们需要让这九个数字必须出现而且仅出现一次,而且满足加法交换律的式子算两种不同的答案,所以根据这个特点想到的是全排列的方法,首先声明一个数字为1-9的列表,交换列表中的各个位置的数字来生成所有的全排列,交换生成全排列可以其实比较简单的是采用交换的递归方法,并且每当生成一个全排列(递归出口)之后那么就需要根据列表中的9个数字每3个数字分为一组形成三个三位数(生成一个9个数字的全排列剩下来的就比较简单了),然后判断第一个数字与第二个数字相加是否等于第三个数字,如果相等那么计数加1,递归结束之后最终将计数结果返回即可,所以这道题的核心就转化为如何生成使用交换的递归方法生成全排列

② 首先一开始的列表是这样的:[1,2,3,4,5,6,7,8,9],交换生成一个排列的过程其实是将当前k这个位置的数字依次与[k,8]范围内的数字进行交换(与本身交换也可以生成一个排列),每个位置都是这样的做法,所以需要在for循环中进行递归,for循环中进行递归是为了尝试与k以及k之后到8这个位置的数字进行交换,也即在递归方法中需要传递一个int类型的参数表示当前交换的位置,并且当当前这一层的递归完成之后那么就需要进行回溯,这样得到的结果才是正确的,回溯的目的是为了在目前这一层的递归结束之后恢复到递归前的状态然后尝试下一个交换继续递归下去,所以核心的代码分别是递归前的数字交换和递归后的回溯:

③ 感觉掌握全排列的写法还是很有好处的(特别是需要理解交换生成全排列的方法,代码很短,其实记住也无妨),可以将一些尝试性的问题转换为1-9数字的全排列进行处理,这种解决办法在某些情境下是一种好办法吧

3. 代码如下(答案好像是336):

from typing import List


# 使用全排列的方法进行解决
def permutation(k: int, nums: List[int], res: List[int]):
    if k == len(nums):
        # print(nums)
        first, second, third, base = 0, 0, 0, 1
        # 将列表中的值转换为三组三位数字
        for i in range(3):
            first += nums[2 - i] * base
            second += nums[5 - i] * base
            third += nums[8 - i] * base
            base *= 10
        if first + second == third:
            # 可以对结果进行输出看是否正确
            #print(first, second, third)
            res[-1] += 1
        return
    for i in range(k, len(nums)):
        # 将k位置上的数字与k~8位置上的数字进行交换
        t = nums[i]
        nums[i] = nums[k]
        nums[k] = t
        permutation(k + 1, nums, res)
        # 回溯, 将列表恢复为递归前的状态, 尝试下一次=个的交换
        t = nums[i]
        nums[i] = nums[k]
        nums[k] = t


if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    # 因为使用全局变量很麻烦所以使用了一个值的列表来存储递归状态计数的问题
    res = [0]
    permutation(0, nums, res)
    print(res[0])

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值