算法(二)枚举算法(穷举法)之火柴棍等式

前言

这是本系列的第二篇文章,从名字就可以看出,将要学习穷举算法,也叫枚举法,噫,有同学可能就要问了,穷举也算算法吗?当然算啦,别拿豆包不当干粮,拿乞丐不当江湖中人,事实上,江湖上很多鼎鼎有名的高手,就来自于天下第一大帮,丐帮。所以,枚举其实也是一种算法思想。现在我们就来学习神功的第二层,枚举算法


实际需求

<Image_1>

也就是火柴等式,比如 1 + 1 = 2,其中1是两根,+号是两根,=号是两根,2是5根火柴。那么如果我们限定可以使用的火柴的根数,一共可以摆出多少个这样符合的等式呢?


枚举算法

题目分析:

首先,我们清楚的指定0 - 9每个数字需要的根数是多少,然后,我们需要去掉4根必须使用的,也就是+号和=号,然后我们把所有的等式摆出来,然后把符合要求的等式打印出来就行了。那么怎么计算一共有多少个?  那么我们最多能形成几位数呢?这些数字中 “1” 所需要用到的火柴最少,也就是说,最多有几位数,我们可以用1、11、111、1111来作为判断标准。所以,n根火柴,最多有  n/2 个 1,所以等式的三个数字的位数 不可能超过 n / 2  / 3 +1 位

         我们已经限定了三个数中的最大数,写一个双层循环,即可得到我们想要的等式。

实现代码
public void enumAlgor(int n){
        int i = n / 2 ;//最多多少个1
        if (i % 3 == 0){
            //说明每个数字,刚好数量相等,
            i = i / 3;
        }else {
            //说明,刚好用完之后,还能剩下几个,那么就+1位
            i = i / 3 + 1;
        }
       
        int sum = 0;
        for (int j = 0; j < i; j++) {
            int z = 1;
            int k = j;
            while ( k > 0){
                z = z * 10;
                k--;
            }
            sum = sum + z;
        }
       
        int count=  0;
        for (int j = 0; j < sum; j++) {
            for ( int o= 0;o < sum ; o++){
                int a = j + o;
                if (accountSum(j) + accountSum(o) + accountSum(a) == n - 4){
                    Log.i("hero",j +" + "+o + " = "+a);
                    count++;
                }
            }
        }
        Log.i("hero","===总共有"+count+"个式子");
    }
private int accountSum(int n){
        //计算数字n需要用多少根火柴
        int z = 0;
        while ( n / 10 != 0){
            z = z + aa[n % 10];
            n = n / 10;
        }
        z += aa[n];//经过很多次除法以后,此时的n是个个位数
        return z;
    }
 // 表示0,需要6根火柴,1需要2根火柴
    private int[] aa = {6,2,5,5,4,5,6,3,7,6};

具体思路
        首先每个数字0-9,需要使用的火柴根数是确定的,也就是数组 aa
         然后,因为“+”号和“=”号需要用去一共四根火柴
         所以,我们能够使用的火柴就是 n-4       
         所以,n根火柴,最多有n/2个1,所以等式的三个数字的大小 不可能超过 n/2 / 3 +1 位
         我们已经限定了三个数中的最大数,写一个双层循环,即可得到我们想要的等式。

运行结果

 enumAlgor(14);

<Image_2>


总结

以上就是本篇文章要和大家分享的枚举算法,其实就是遍历所有的可能性,然后根据条件进行剔除,就可以得到所有满足条件的结果。但是枚举算法在很多时候并不是最优的算法,但是也是比较重要的一种算法思想。所以不要因为简单,就不重视他。加油,好好学习,早晚会成为武林高手的。
因个人水平有限,难免和不足之处,请多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值