图解算法习题之老王的杂货铺

原题:老王开杂货店想送N块冬瓜糖砖给客户,每块冬瓜糖砖长宽高都是10厘米。老王希望将这N块冬瓜糖砖包成一大包(x*y*z的长方体),以方便运送,但为了响应环保,希望使用的包装纸越少越好。编写一个程序输入N,输出最少的包装纸面积。

上面的题目可以简化为:将N块体积为1的正方体堆成长方体,求最小面积。

在不用大量数据看规律的情况下,我是这么思考的。(因为看数据没看出有什么规律。。。。。。)

长方体表面积公式:S = 2(x*y+x*z+y*z),当且仅当x=y=z的时候,表面积最小。但是边长是整数,这种情况很少存在,所以我们只要找到各个边长差绝对值的和最小的边长即可。

但是怎么将小正方体的个数,分成长宽高呢?分解质因数。废话不多少,直接上代码。可以先运行看看,然后再看代码。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>分解质因数</title>
    </head>
    <body>
        
        个数:<input type="text" id="inp"/><br>
        质因数:<span id="zys"></span><br>
        最小表面积:<span id="bmj"></span><br>
        <!-- <input type="button" value="求质因数" onclick="getZys()"/> -->
        <input type="button" value="求最小表面积" onclick="getBmj()"/>
        <script>
            
            function getZys(){
                var n = Number(document.getElementById("inp").value);
                var zys = new Array();        //质因数
                var num = 0;
                var m = n;
                for(var i = 2; i <= n; i++){
                    if(n % i == 0){
                        zys[num] = i;
                        num++;
                        n = (n/i);
                        i--;
                    }
                }
                if (num < 2)
                    document.getElementById("zys").innerHTML = m + "为质数";
                else {
                    var out = m + "=" + zys[0];
                    for (var k = 1; k < num; k++) {
                        out += "*" + zys[k];
                    }
                    document.getElementById("zys").innerHTML = out;
                    console.log(m+"共有"+num+"个质因数");
                }
            }
            
            
            function getBmj(){
                getZys();
                var n = Number(document.getElementById("inp").value);
                var zys = new Array();        //质因数
                var num = 0;
                var m = n;
                var bmj;
                for(var i = 2; i <= n; i++){
                    if(n % i == 0){
                        zys[num] = i;
                        num++;
                        n = (n/i);
                        i--;
                    }
                }
                
                var scfg = Math.pow(m,1/3);        //开三次方(有误差,精准的请用math.js)
                
                if (num < 2){    //排成一条线
                    bmj = m * 4 + 2;
                }else if(Math.floor(scfg) === scfg){    //正方体
                    bmj = scfg * scfg * 6;
                }else{
                    if(num == 2){            //两个质因数,1为其中的一个边长
                        bmj = 2 * (zys[0] + zys[1] + zys[0] * zys[1]);
                    }else if(num == 3){        //3个质因数,三个边长
                        bmj = 2 * (zys[0]*zys[1] + zys[0] * zys[2] + zys[1]*zys[2]);
                    }else{                    //多个质因数
                        /*需要组合了,组合成三个边长,将三个边长之差的绝对值相加,最小的那组作为边长*/
                        /*组合应该可以用循环写出来,但还没想好怎么写*/
                        bmj = "肉眼组合";    
                    }
                }
                document.getElementById("bmj").innerHTML = bmj;
            }
            
        </script>
    </body>
</html>

上面的代码是不完整的,对于质因子个数大于3个的情况,我只能想到组合了,目前没想到什么其他的方法。但是组合还没想好怎么写,还请各大牛人指导一下,顺便给编辑部提提意见,出了题最起码给个答案啊。我也比对过数据,我是没看出规律,可以贡献出来,给大家看看。

 

posted @ 2019-06-10 17:28  半瓶假酒  阅读(397)  评论(0编辑  收藏  举报