换酒问题
小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒。你购入了 numBottles 瓶酒。
如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。
请你计算 最多 能喝到多少瓶酒。
方法一是比较简单的,简单理解,就是给一个除数一个被除数,然后进行除法的循环,新的被除数是上次一次的商+余数,当余数为0的时候结束循环。
说一下方法二,公式法。
假设现在有b瓶酒,e个瓶子能换一瓶新的,那么每换一次就会消耗掉e-1个瓶子。
怎样才能保证现在剩下的瓶子可以换新酒呢,得满足以下不等式:
b − n ( e − 1 ) ≥ e ( 1 ) b - n(e - 1) \geq e \ \ \ \ \ \ (1) b−n(e−1)≥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 b−n(e−1)=e的情况,可以得到 n = b − e e − 1 n = \frac{b-e}{e-1} n=e−1b−e,而此时还剩下 b − n ( e − 1 ) b - n(e - 1) b−n(e−1)瓶酒,也就是 e e e瓶酒,还能换一次,也就是说,总共进行了 n = b − e e − 1 + 1 n = \frac{b-e}{e-1}+1 n=e−1b−e+1次换酒的行为,那么也就多喝了这么多酒。因此总的喝掉的酒的数量就是 b + b − e e − 1 + 1 b + \frac{b-e}{e-1}+1 b+e−1b−e+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;
}
}
这是鄙人的公众号,感兴趣可以关注一波哦。