蓝桥杯-寒假作业

题目:

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
每个方块代表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;
}
posted @ 2019-12-07 12:05  帅气的涛啊  阅读(731)  评论(1编辑  收藏  举报