从零开始学算法(二)枚举算法(穷举法)之火柴棍等式

来源:互联网 发布:淘宝客服规章制度 编辑:程序博客网 时间:2024/06/10 09:22

前言

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


实际需求

<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>


总结

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

0 0
原创粉丝点击