问题描述
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
每个方块代表 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
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
答案提交
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
答案:64
题解一
全排列:
#include <iostream>
#include <algorithm>
using namespace std;
int ans;
int a[13] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int main()
{
do
{
if(a[0] + a[1] == a[2] &&
a[3] - a[4] == a[5] &&
a[6] * a[7] == a[8] &&
a[10] * a[11] == a[9]) ans ++;
}while(next_permutation(a, a + 13));
cout << ans << endl;
return 0;
}
ps:13! ≈ 6.2 × 109,实测该程序要运行 6 分钟左右(⊙﹏⊙)
题解二
DFS(剪枝):
解题思路
:
- 边搜索边剪枝,若某个表达式不合法,则直接结束该分支;
- 为了避免出现
10 / 5 = 2
、11 / 5 = 2
这个情况,可以将除法转换成乘法;
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int ans;
bool used[15];
vector<int> a;
void dfs(int u)
{
if(u == 3 && a[0] + a[1] != a[2]) return;
if(u == 6 && a[3] - a[4] != a[5]) return;
if(u == 9 && a[6] * a[7] != a[8]) return;
if(u == 13)
{
if(a[10] * a[11] == a[9]) ans ++;
return;
}
for (int i = 1; i <= 13; i ++)
if(!used[i])
{
used[i] = true;
a.push_back(i);
dfs(u + 1);
a.pop_back();
used[i] = false;
}
}
int main()
{
dfs(0);
cout << ans << endl;
return 0;
}