换酒问题

换酒问题

小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入了 numBottles 瓶酒。
如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。
请你计算 最多 能喝到多少瓶酒。

方法一是比较简单的,简单理解,就是给一个除数一个被除数,然后进行除法的循环,新的被除数是上次一次的商+余数,当余数为0的时候结束循环。

说一下方法二,公式法。
假设现在有b瓶酒,e个瓶子能换一瓶新的,那么每换一次就会消耗掉e-1个瓶子。
怎样才能保证现在剩下的瓶子可以换新酒呢,得满足以下不等式:

            b − n ( e − 1 ) ≥ e        ( 1 ) b - n(e - 1) \geq e \ \ \ \ \ \ (1) bn(e1)e      (1)

怎么理解呢,假设总共有5个酒瓶,3个酒瓶能换瓶新酒,那么换一次就是失去3个酒瓶得到1瓶酒,也就是说,进行的这一次换酒操作,就相当于在原有的5个酒瓶的基础上失去了2个酒瓶,此时还剩下3个酒瓶。再换一次,又失去两个酒瓶,此时还剩下1个酒瓶,因为3个酒瓶才能换一瓶新酒,所以此时就不能再继续换了,整个流程就结束了。

当然换的酒还是自己喝了,也就是说换了几次就多喝了几瓶酒,上面的例子中,因为换了两次,所以就多喝了2瓶,那么总共就喝了7瓶酒。

那么现在的问题就是怎么计算公式(1)中的n了,n是几,那么就多喝了几瓶。

先计算 b − n ( e − 1 ) = e b - n(e - 1) = e bn(e1)=e的情况,可以得到 n = b − e e − 1 n = \frac{b-e}{e-1} n=e1be,而此时还剩下 b − n ( e − 1 ) b - n(e - 1) bn(e1)瓶酒,也就是 e e e瓶酒,还能换一次,也就是说,总共进行了 n = b − e e − 1 + 1 n = \frac{b-e}{e-1}+1 n=e1be+1次换酒的行为,那么也就多喝了这么多酒。因此总的喝掉的酒的数量就是 b + b − e e − 1 + 1 b + \frac{b-e}{e-1}+1 b+e1be+1

当然,如果一开始酒瓶数就不够,比如现在只买了2瓶酒,但是3个酒瓶才能换一瓶新酒,那么从一开始就不满足公式(1),也就没法换酒了,只能喝两瓶。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main1 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] strArr = bf.readLine().split(" ");
        int[] intArr = Arrays.asList(strArr).stream().mapToInt(Integer::parseInt).toArray();
        Solution1 solution = new Solution1();
        int bottleNum = solution.numWaterBottles2(intArr[0], intArr[1]);
        System.out.println("The number of bottle is " + bottleNum);
    }
}

//定义类
class Solution1 {
    /**
     * 方法一
     */
    //定义方法(参数是 当前瓶子总数,兑换规则即兑换的瓶子数)\
    public int numWaterBottles1(int numBottles, int numExchange) {
        //定义商即可兑换多少瓶新饮料,定义余数即一次兑换后剩下了几瓶,定义当前有多少瓶
        int numBottlesExc = 0;
        int numBottlesRem = 0;
        int numBottlesCur = numBottles;
        //定义结果
        int result = numBottles;
        //利用while循环,结束条件为当前总瓶子数小于兑换数
        while (numBottlesCur >= numExchange) {
            //总瓶子数除兑换瓶子数得到商
            numBottlesExc = numBottlesCur / numExchange;
            //得到余数
            numBottlesRem = numBottlesCur % numExchange;
            //得到当前总瓶子数 (商+余数)
            numBottlesCur = numBottlesExc + numBottlesRem;
            // 统计喝到的总的饮料数
            result += numBottlesExc;
        }
        return result;
    }

	/**
	*方法二:公式法
	*/
    //定义方法(参数是 当前瓶子总数,兑换规则即兑换的瓶子数)
    public int numWaterBottles2(int numBottles, int numExchange) {
        // 判断当前总瓶数是否大于交换条件,如果是就利用公式,否则就直接返回当前瓶数
        return numBottles >= numExchange ? numBottles + (numBottles - numExchange) / (numExchange - 1) + 1 : numBottles;
    }
}

在这里插入图片描述
这是鄙人的公众号,感兴趣可以关注一波哦。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值