用空瓶和瓶盖换酒喝

4 篇文章 0 订阅

前几天看到一个很有意思的智力题,题目大大致意思如下:啤酒每瓶2元,4个瓶盖或者2个空酒瓶可以换一瓶啤酒,当瓶盖或者空酒瓶不足以换取一瓶瓶酒时可以向商家借若干瓶盖或者空酒瓶,只要能够还得上,请问给你10元,最多可以喝多少瓶瓶酒?

一眼看上去还真有点无从下手,于是我拿出纸盒笔在写下了下面买酒的过程:

第1次:买5瓶;喝完后剩5空瓶+5盖;
第2次:换3瓶;剩1空瓶+1盖,喝完后剩4空瓶+4盖;
第3次:换3瓶;剩0空瓶+0盖,喝完后剩3空瓶+3盖;
第4次:换1瓶;剩1空瓶+3盖,喝完后剩2空瓶+4盖;
第5次:换2瓶;剩0空瓶+0盖,喝完后剩2空瓶+2盖;
第6次:换1瓶;剩0空瓶+2盖,喝完后剩1空瓶+3盖;找人借1盖;
第7次:换1瓶;剩1空瓶-1盖,喝完后剩2空瓶+0盖(把盖还给别人);
第8次:换1瓶;剩0空瓶+0盖,喝完后剩1空瓶+1盖;找人借1空瓶;
第9次:换1瓶;剩-1空瓶+1盖,喝完后剩0空瓶+2盖(有借有还),再借2盖;
第10次:换1瓶;剩0空瓶-2盖,喝完后剩1空瓶-1盖(还一个盖);再借1空瓶;
第11次:换1瓶;剩-1空瓶-1盖,喝完后剩0空瓶0盖;酒喝完了帐也清了。
一共是20瓶。

有了以上过程,我想写起代码来应该就比较简单了,下面贴出具体的实现:

public static void main(String[] args) {
        int cap, bottle, sum;// cap瓶盖个数,bottle 空瓶个数,sum喝到的啤酒数;
        cap = bottle = sum = 14 / 2; // 未兑换前个数
        while (!(cap == 0 && bottle == 0)) {
            if (cap > 3 || bottle > 1) {// 当空瓶子或者盖子足够换一瓶啤酒的情况
                sum = sum + cap / 4; // 用盖子兑换
                sum = sum + bottle / 2; // 用空瓶子兑换
                int bottlenew = bottle % 2 + (cap / 4 + bottle / 2);// 兑换后剩下的瓶子数
                int capnew = cap % 4 + (cap / 4 + bottle / 2);// 兑换后剩下的瓶盖数
                bottle = bottlenew;
                cap = capnew;
            }
            if (cap == 3 && bottle < 2) {// 有三个盖子,且空瓶数不多与一个的时候可以向卖家借一个瓶盖换一瓶酒
                cap = 0;// 换的一瓶酒后喝完可以得到一个空瓶和一个瓶盖,瓶盖还给卖家
                sum += 1;
                bottle += 1;
            }
            if (bottle == 1 && cap < 3) {// 如果瓶盖少于三个,而空瓶数为一个时,可以向卖家借一个空瓶换一瓶啤酒
                bottle = 0;// 换的一瓶酒后喝完可以得到一个空瓶和一个瓶盖,空瓶还给卖家
                sum += 1;
                cap += 1;
            }
            if (cap == 2 && bottle < 1) {// 没有剩余的空瓶子,但是手上有两个瓶盖时可以向卖家借两个瓶盖
                cap = -1;// 喝完以后得一个空瓶和一个瓶盖,但是借了卖家两个瓶盖,所以此时还欠一个瓶盖
                sum += 1;
                bottle += 1;// 获得一个空瓶子,又可以转到上一个if语句进行计算
            }
        }
        System.out.println("总共喝了 " + sum + " 瓶酒");
        System.out.println("剩下  " + cap + " 个盖子和  " + bottle + " 个空瓶");
    }

下面给大家看看某位自称精通C++的大神写的C++代码:
这里写图片描述
这里写图片描述
看了这代码,当时我就觉得自己弱爆了,我问大神:“如果给你10000元,能买几瓶啤酒呢?”大神久久没有回复我,估计已经埋头写了几万行代码了吧。

最后贴出一种极其简单的方法,都说了是智力题,那个肯定还有更简单的方法。假设我们最后最多能够喝到N瓶啤酒,那么瓶数N和给定的钱数M还有瓶酒单价P,可换瓶酒的盖子数cap和空瓶数bottle存在下面的关系:N=N/cap+N/bottle+M/p.将上式子化简的:N=M/P*cap*bottle/(cap*bottle-cap-bottle),那么接下来代码就很简单了:

    public static void main(String[] args) {
        int m = 10, p = 2, cap = 4, bottle = 2;
        SumBeer(m, p, cap, bottle);
    }

    public static void SumBeer(int m, int p, int cap, int bottle) {
        if (m >= p) {
            int n = (m / p) * cap * bottle / (cap * bottle - cap - bottle);
            System.out.println("总共可以喝:" + n + "瓶啤酒!");
        } else {

            System.out.println("穷鬼,你连一瓶啤酒都喝不上!快看看兜里还有钱没!");
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值