蓝桥杯-寒假作业
题目:
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
每个方块代表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
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
解法:
首先想到深度优先搜索进行排列组合,便有了如下的代码:
#include <bits/stdc++.h>
using namespace std;
int a[13] = {0}; //记录当前序列
int book[14] = {0}; // 记录下标数字是否被使用
int num = 0; //计数器
void dfs(int step) {
if (step == 13) {
if (a[12] * a[11] == a[10] && a[7] * a[8] == a[9] &&
a[4] - a[5] == a[6] && a[1] + a[2] == a[3]) {
num++;
// for(int i=1;i<=12;i++)
// cout<<a[i]<<" ";
// cout<<endl;
}
return;
}
for (int i = 1; i <= 13; i++) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main() {
dfs(1);
cout << num << endl;
return 0;
}
运行你就会发现运行不出来,时间过于长!因为排列组合太多:13个选项中选出12数排列组合,你就会发现是一个很大的数。
然后就要优化时间复杂度,优化思想来源于:https://blog.csdn.net/Monkeyhour/article/details/79771107
#include <bits/stdc++.h>
using namespace std;
int a[20] = {0}; //记录当前序列
int book[20] = {0}; // 记录是否被访问
int num = 0; //计数器
void dfs(int step) {
if (step >= 4 && a[1] + a[2] != a[3])
return;
if (step >= 7 && a[4] - a[5] != a[6])
return;
if (step >= 10 && a[7] * a[8] != a[9])
return;
if (step == 13 &&
a[12] * a[11] == a[10]) //能进行到这里,就证明以上的条件都满足了
{
num++;
// for(int i=1;i<=12;i++)
// cout<<a[i]<<" ";
// cout<<endl;return;
}
for (int i = 1; i <= 13; i++) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main() {
dfs(1);
cout << num << endl;
return 0;
}
本文来自博客园,作者:帅气的涛啊,转载请注明原文链接:https://www.cnblogs.com/handsometaoa/p/12001266.html