1. 问题描述:
现在小学的数学题目也不是那么好玩的。 看看这个寒假作业:
每个方块代表1~13中的某一个数字,但不能重复。 比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
输出
请填写表示方案数目的整数。
来源:http://oj.ecustacm.cn/problem.php?id=1285
2. 思路分析:
分析题目可以知道我们可以将1-13个数字填入到方块中看是否满足题目中四个算式中的运算,所以需要尝试所有的可能性,一个比较容易想到的方法是递归生成全排列,然后将数字填到方格中看是否满足条件,下面使用的是for循环中交换列表(python语言使用列表,c/c++/java语言使用数组)中的元素递归生成全排列,在递归的出口依次判断对应位置的数字经过运算之后是否相等,如果四个等式运算的结果都满足那么计算加1,最终输出计数的结果即可。使用python语言很久都计算不出来,后面转换为java语言使用相同的思路计算出结果为64(java也需要等待几十秒),并且在递归的出口可以输出对应的列表中元素的值看是否正确。
3. 代码如下:
python代码(没有计算出最终的结果):
from typing import List
res = 0
def permutation(index: int, nums: List[int]):
# 属于global关键字修改全局变量
global res
if index == 13:
# 判断是否满足要求
if nums[0] + nums[1] != nums[2]: return
if nums[3] - nums[4] != nums[5]: return
if nums[6] * nums[7] != nums[8]: return
if nums[9] != nums[10] * nums[11]: return
res += 1
return
for i in range(index, 13):
# 交换元素递归生成全排列
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(1, 14)]
permutation(0, nums)
print(res)
java代码:
public class Main {
public static void main(String[] args) {
int nums[] = new int[13];
for (int i = 1; i < 14; ++i){
nums[i - 1] = i;
}
permutation(0, nums);
System.out.println(res);
}
static int res = 0;
public static void permutation(int index, int []nums){
if (index == 13){
if (nums[0] + nums[1] != nums[2]) return;
if (nums[3] - nums[4] != nums[5]) return;
if (nums[6] * nums[7] != nums[8]) return;
// 转换为乘法可以避免精度的问题
if (nums[11] * nums[10] != nums[9]) return;
for (int i = 0; i < 13; ++i){
System.out.print(nums[i] + " ");
}
System.out.println();
res += 1;
return;
}
for (int i = index; i < 13; ++i){
int t = nums[i];
nums[i] = nums[index];
nums[index] = t;
permutation(index + 1, nums);
//回溯
t = nums[i];
nums[i] = nums[index];
nums[index] = t;
}
}
}