1. 问题描述:
小明的作业本上有道思考题:算式: (□□□□-□□□□)*□□=900。其中的小方块代表0~9的数字,这10个方块刚好包含了0~9中的所有数字。注意:0不能作为某个数字的首位。小明经过几天的努力,终于做出了答案!如下:(5012-4987)*36=900 。计算机搜索后,发现还有另外一个解,本题的任务就是:请你算出这另外的一个解。
输出
输出格式需要与示例严格一致;
括号及运算符号不要用中文输入法;
整个算式中不能包含空格。
来源:http://oj.ecustacm.cn/problem.php?id=1332
2. 思路分析:
分析题目可以知道我们需要生成0-9数字的全排列,将这10个数字填入到空格中看等式是否成立,所以关键在于生成全排列,下面使用的是交换列表元素递归生成全排列的方法,其实都是一些基本的套路,记住即可。递归方法中传递一个int类型的变量用来记录当前当前递归的位置,一个包含若干个元素的列表表示交换元素之后生成的排列,在for循环中尝试将当前的位置与当前位置之后的数字交换一直递归下去直到递归的位置等于列表的长度的时候说明一个排列已经生成,这个时候判断列表中的对应元素是否满足等式如果满足那么输出对应的结果即可。除了使用交换元素递归生成全排列的方法,还可以直接调用python中itertools模块中的permutations方法生成全排列,通过遍历permutations()方法调用的返回值对应的元组类型,元组中的元素就为当前排列对应的数字,python中的permutations()方法生成全排列还是挺方便的。最终的答案是:(6048-5973)*12=900
3. 代码如下:
交换列表元素递归生成全排列:
from typing import List
def permutation(index: int, nums: List[int]):
# index表示当前递归的位置
if index == len(nums):
if (nums[0] * 1000 + nums[1] * 100 + nums[2] * 10 + nums[3] - (
nums[4] * 1000 + nums[5] * 100 + nums[6] * 10 + nums[7])) * (nums[8] * 10 + nums[9]) == 900:
# 使用format格式化字符串输出
print(
"({}{}{}{}-{}{}{}{})*{}{}=900".format(nums[0], nums[1], nums[2], nums[3], nums[4], nums[5], nums[6],
nums[7], nums[8], nums[9]))
return
for i in range(index, len(nums)):
# 交换元素位置的方法生成全排列
t = nums[i]
nums[i] = nums[index]
nums[index] = t
permutation(index + 1, nums)
# 回溯
t = nums[i]
nums[i] = nums[index]
nums[index] = t
if __name__ == '__main__':
nums = [i for i in range(10)]
permutation(0, nums)
itertools模块中的permutations方法生成全排列:
import itertools
if __name__ == '__main__':
nums = [i for i in range(10)]
cur = itertools.permutations(nums, 10)
# 遍历permutations方法的返回值得到的是元组类型
for num in cur:
# num为元组类型
if ((num[0] * 1000 + num[1] * 100 + num[2] * 10 + num[3]) - (
num[4] * 1000 + num[5] * 100 + num[6] * 10 + num[7])) * (num[8] * 10 + num[9]) == 900:
print("({}{}{}{}-{}{}{}{})*{}{}=900".format(num[0], num[1], num[2], num[3], num[4], num[5], num[6],
num[7], num[8], num[9]))