A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曾翀   /  2014-7-30 21:09  /  8395 人查看  /  118 人回复  /   3 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Test10 {
       
        public static void main(String[] args) {
               
                System.out.println("#####################方法一检测#####################");
                System.out.println(buyCoke1(28));
                System.out.println(buyCoke1(50));
                //检测当人数能被3整除的情况
                System.out.println(buyCoke1(99));
               
                System.out.println("#####################方法二检测#####################");
                System.out.println(buyCoke2(28));
                System.out.println(buyCoke2(50));
                System.out.println(buyCoke3(99));
               
                System.out.println("#####################方法三检测#####################");
                System.out.println(buyCoke3(28));
                System.out.println(buyCoke3(50));
                System.out.println(buyCoke3(99));
               
                System.out.println("#####################健壮方法检测#####################");
                System.out.println(buyCoke(28,1,3));
                System.out.println(buyCoke(50,1,3));
                System.out.println(buyCoke(99,1,3));
                System.out.println(buyCoke(2014,7,9));
        }
        /*
         * 思路:最后剩下的瓶盖,加上每个人喝掉的可乐,等于购买的可乐。
         *
         * 1、最后余下的瓶盖数capLeft,capLeft取值只可能是1、2、3(为什么会出现3呢?请见下面第3条分析。);计算式capLeft=28%3
         * 2、一瓶可乐相当于3个瓶盖,每个人假如喝掉一瓶可乐(喝完可乐剩下一个瓶盖),则相当于每个人消费了2个瓶盖换取的可乐;
         * 那么28个人喝掉的可乐转换成瓶盖总量,计算式28*2
         * 3、总共瓶盖等于capLeft+28*2,即等于购买的可乐转换成的瓶盖数:bottleAll*3=capLeft+28*2
         * 4、为什么会出现最后剩余瓶盖数为3呢?
         *   a、当总人数除3的余数是1的情况时,就会出现这种情况;
         *   b、先举例理解,如27个人时:当26个人都喝到了可乐,这时剩下2个瓶盖,有一种办法是去借一个瓶盖,然后凑足3个瓶盖换了一瓶可乐给第27个喝了,
         *   然后产生的那个瓶盖再还给别人;但是我们找不到人借瓶盖,只能再买一瓶可乐,给第27个人,剩下一个瓶盖加上前面的2个,就剩下了3个;
         *   c、所以,用上面3步分析出来的结果:27个人应该是需要买18瓶,但是就会产生举例分析时的尴尬境地;所以27个人时应该是买27瓶,最后余3个瓶盖;
         *   即:当人数除3余0时,结果是前3步的计算结果再加1;
         *   d、此分析也要加入到下面2个方法的分析中。
         */
        //方法一:
        public static int buyCoke1(int num){
               
                //最后余下的瓶盖数capLeft
                int capLeft = num%3;
               
                //根据等式bottleAll*3=capLeft+28*2,总瓶盖数除3则是需要买的可乐瓶数
                int bottleAll = (num*2+capLeft)/3;
               
                //如果人数能被3整除,则返回bottleAll+1
                if(capLeft == 0)
                        return bottleAll+1;
               
                //否则返回bottleAll
                return bottleAll;
        }
       
        /*
         * 思路:假设每个人手上现在购买了两个瓶盖,则再需要加入1个瓶盖,就能使这个瓶盖循环利用,使大家都喝到可乐。
         *
         * 1、每个人手上有2个瓶盖,则有capUse = 28*2个瓶盖;
         * 2、考虑到方法一的第4条分析,再额外添加1-3个瓶盖,就能让所有人喝到可乐;
         * 3、capUse除3则是实际喝掉的可乐,考虑到不能整除情况下的类型自动提升为int,
         * 则计算出的需要买的可乐瓶数为capUse/3 + 1;此时也满足了当人数是3的倍数的分析。
         */
        //方法二:
        public static int buyCoke2(int num){
               
                //每个人手上有2个瓶盖,则有capUse = 28*2个瓶盖
                int capUse = num*2;
               
                //需要买的可乐瓶数为capUse/3 + 1
                return capUse/3+1;
        }
       
        /*
         * 思路:一瓶可乐相当于3个瓶盖,每个人假如喝掉一瓶可乐(喝完可乐剩下一个瓶盖),则相当于每个人实际喝掉了2/3瓶可乐。
         *
         * 1、总共喝掉的可乐瓶数为2/3*num,考虑到这个计算结果是浮点型,其中2/3对应的浮点数会被类型提升,则强制转型double bottleUse = (double)2/3*num;
         * 2、参考方法一的第4条分析;由于最后会剩下1-3个瓶盖,则总共买的可乐瓶数是刚好大于bottleUse的整数;
         * 3、所以采用Math.ceil方法,并且把返回的double数强转为int型;
         * 4、加入判断,满足了当人数是3的倍数的分析;
         * 5、参考方法二的第3条分析,则可将第3、4步简化为int bottleAll = bottleUse + 1,且不再做判断。
         */
        //方法三:
        public static int buyCoke3(int num){
               
                //由于每个人实际相当于喝掉了2/3瓶可乐,则实际喝掉的可乐为bottleUse
                double bottleUse = (double)2/3*num;
               
                return (int)(bottleUse + 1);
        }
       
        //健壮函数,封装方法(采用方法二):
        //分别传入参数:假设人数为num,每人要喝numBottle瓶可乐,每numCap个瓶盖可以换一瓶可乐,则需要买多少瓶可乐呢?
        //使用JDK1.5新特性,可变参数
        public static int buyCoke(int ... args){
               
                //每个人手上的瓶盖数为args[1]*2,所有人手上瓶盖数int capUse = args[0]*args[1]*2
                int capUse = args[0]*args[1]*2;
               
                //需要购买的可乐瓶数为capUse/args[2]+1
                return capUse/args[2]+1;
        }
}
回复 使用道具 举报
看看~~~~~~~~~~
回复 使用道具 举报
都是大神。。。。
回复 使用道具 举报
看的头晕啊!!!!!!!!!!!
回复 使用道具 举报
大神都在
回复 使用道具 举报
这题涉及到动态规划问题   瓶盖换过来的可乐也是有瓶盖的  这需要考虑进去
回复 使用道具 举报
回复 使用道具 举报
我的算法
cola = (person - 1) / 3 * 2 + (person - 1) % 3 + 1

按照现实生活的话,不可以佘饮料,所以从第二个人开始分组,3人一组,每组买两瓶,不够3人的组每人买一瓶,第一个人买一瓶
回复 使用道具 举报
LFW 发表于 2014-7-31 16:20
我又想了一下,不对,,4人成团买3支没有错,但是每12个人分成三组,买了9瓶,分别各组兑换一次刚好喝完 ...

28人的一共买多少??我算得是19瓶!  4人一组先买3*6=18瓶,28人中有24个人喝到,剩余6个瓶盖,换两瓶,26个人喝到,剩余2个瓶盖,买1瓶,27人喝到,三个瓶盖,换一瓶,28人全喝到!!
回复 使用道具 举报
五个人你买几瓶,六个人你买几瓶   

点评

五个人买四瓶,6个人还是买四瓶 公式说的  发表于 2014-8-8 14:52
回复 使用道具 举报
到处玩的 来自手机 中级黑马 2014-8-6 08:16:05
91#
hejinzhong 发表于 2014-7-31 06:15
(1)如果只要有盖子就可以换,那就是这样来写
2个人先买2瓶,将盖子给第3人,第三人即可免费喝一瓶了(先 ...

不对,买来的瓶子盖拿去换新的了,但是换来的瓶子(上面有盖),也是可以换的,所以你说的方法肯定不是买的最少的
回复 使用道具 举报
到处玩的 来自手机 中级黑马 2014-8-6 08:20:34
92#
357016138 发表于 2014-7-31 01:34

这个思路利用了换来的瓶子盖,应该是正确的思路。
回复 使用道具 举报
很简单,买三瓶可乐够四个人喝,然后(28/4)*3+(28%4)
回复 使用道具 举报
hejinzhong 发表于 2014-7-31 06:15
(1)如果只要有盖子就可以换,那就是这样来写
2个人先买2瓶,将盖子给第3人,第三人即可免费喝一瓶了(先 ...

跟我想的一样!
这个写法最简单了!
回复 使用道具 举报
楼上威武
回复 使用道具 举报
有问题  换的那瓶也有个瓶盖  算在下一个三瓶里面吧
回复 使用道具 举报

这位兄台的分析太好了。感谢分享:handshake
回复 使用道具 举报
很厉害!!!!!!!
回复 使用道具 举报
hejinzhong 发表于 2014-7-31 06:15
(1)如果只要有盖子就可以换,那就是这样来写
2个人先买2瓶,将盖子给第3人,第三人即可免费喝一瓶了(先 ...

如果num=3,你这个就不对了啊!
回复 使用道具 举报
hejinzhong 发表于 2014-7-31 06:15
(1)如果只要有盖子就可以换,那就是这样来写
2个人先买2瓶,将盖子给第3人,第三人即可免费喝一瓶了(先 ...

4个人抱团后会多一个盖子。光这12盖子就可以再换5瓶还剩下两个盖子,然后再借一瓶,还回去3个盖子。
所以说你的思想是错的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马