一、题目
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
题目链接:牛客网链接
二、思路
使用递归来解决:
由于每次可以用现有的瓶子数目来兑换汽水,兑换到汽水后又可以产生瓶子又可以兑换汽水,很明显可以用循环或者递归来解决。特殊情况一:当瓶子数目小于2的时候换不到汽水。特殊情况二:当瓶子数目等于二的时候,刚好可以换到一瓶汽水。其他情况用计算出来的空瓶子数目不断递归。递归公式如下:
用递归能解决的问题,循环也能够解决,思路参照上面的思路。
三、代码
递归
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
// 传入空瓶子的数目
int emptyBottleNumber = scanner.nextInt();
// 输出最大可以换到的汽水数目
System.out.println(maxSodaNumber(emptyBottleNumber));
}
}
private static int maxSodaNumber(int emptyBottleNumber) {
// 特殊情况一:瓶子数量小于二的话,就换不到汽水
if (emptyBottleNumber < 2) {
return 0;
}
// 特殊情况二:瓶子数量为二的话,刚好可以换到一瓶
if (emptyBottleNumber == 2) {
return 1;
}
// 最后返回的结果
int count = 0;
// 当前有的瓶子可以换到的汽水数
int currentChange = emptyBottleNumber / 3;
count = count + currentChange;
// 剩余瓶子数
int remainBottles = emptyBottleNumber % 3;
// 输入参数(换到的汽水数目和剩余瓶子)进行递归
count = count + maxSodaNumber(currentChange + remainBottles);
return count;
}
}
非递归
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
// 传入空瓶子的数目
int n = scanner.nextInt();
// 输出最大可以换到的汽水数目
System.out.println(drink(n));
}
}
private static int drink(int n) {
// 材料总数
int total = 0;
// 传进来的空瓶子大于2才能换到汽水
while (n > 2) {
total = total + n / 3;
// 新的空瓶子数目
n = n / 3 + n % 3;
}
// 特殊情况处理
if (n == 2) {
total++;
}
return total;
}
}