洛谷 1149.火柴棒等式

这道题其实也是全排列型递归的一种。

思路:首先我们读题,这里的每一个数字需要的火柴棒需要我们自己输入,我们这里用数组xuanze来代表从0-9数字所用的火柴棒的数目。并且,我们需要开大数组,不然的话会因为数组的个数不同而造成bug。

然后我们去想,既然是一个A+B=C的等式,那么我们需要考虑的就是三个数的选择是什么。我们发现,这里面的数有类似于全排列的倾向,所以我们就可能会用到全排列的方法去递归,但是我们看到这里的数字可能是相同的,而我们平常写的全排序是不会出现重复数字的,所以这里在写模板的过程中我们不能写判断状态的那个判断条件if,因为这里的数字是可以重复的。

再来,递归的第一个变量应该是选择的数的位置在第几个,第二个变量就是记录火柴棒的个数的当然你也可以直接在dfs中加入,不用两个变量也行。当等于3的时候我们就开始终止,判断:

1.它的等式是不是成立的

2.它的火柴棒个数是不是n-4.

注意:这里n-4是因为+和=各需要2个火柴棒,所以需要先减去。

这样就写成了。我们需要注意一下范围,虽热说n<=24,但是当我们遇到比较大的数的时候,我们还需要有所优化,比如剪枝,大家可以酌情选择是否剪枝。当然,能剪枝是最好的。

范围上,如果开的太小,有可能得出的结果是不一样的,特别是数组xuanze,如果你开的正好是10,那么就不会得到正确答案,因为其他位置你都没有定义i,程序不会自然的认为它是0的。所以需要开的比较大才行,注意这点,一开始作者也是在这里犯错的。

这里的cloo函数其实就是对于当我们遍历的数字超过10的时候,我们需要重新判断火柴棒的数目,这里就是对于超过10的数上的保险。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 1000
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
typedef long long LL;
int n, m, counts;
LL arr[MAX]={-1};
LL st[MAX];
LL heihei;
LL mem[MAX][MAX];
LL xuanze[MAX] = { 6,2,5,5,4,5,6,3,7,6 };
map<LL, LL>M;
bool flag = false;
int cloo(int x) {
    if (xuanze[x])
        return xuanze[x];
    else {
        int sum = 0;
        while (x) {
            sum += xuanze[x%10];
            x /= 10;
        }
        return sum;
    }
}
void dfs(int u,int sum) {
    if (sum > n)
        return;
    if (u == 3) {
        if (arr[0] + arr[1] == arr[2]&& sum == n)
                counts++;
   
        return;
    }
    for (int i = 0; i <= 1000; i++) {
        arr[u] = i;
        dfs(u + 1,sum+cloo(i));
        arr[u] = 0;
    }
    
}
int main() {
   
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    cin >> n;
    n -= 4;
    dfs(0,0);
    cout << counts << endl;

    return 0;
}

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值