今天有人在java交流群里面有人问到一个算法问题:
一个算法题:
啤酒2块钱1瓶,
4个瓶盖换1瓶
2个空瓶换1瓶
问:10块钱可以喝几瓶?
首先,可以用10元买下5瓶啤酒,然后得到5个酒瓶和5个瓶盖,然后又可以用酒瓶和瓶盖兑换啤酒,得到的啤酒又可以有酒瓶和瓶盖,然后又能兑换啤酒。。。。如此反复。。但是多个瓶盖和酒瓶才能兑换一瓶啤酒,所以总有不能再兑换的时候。
以下是我的代码:
/**
* 2018-04-13
* @author liujie
*/
public class TestBeer {
private static final int CAP_TO_BEER = 4; // 4个瓶盖兑换一瓶啤酒
private static final int BOTTLE_TO_BEER = 2; // 2个瓶子兑换一瓶啤酒
private static final int MONEY_TO_BEER = 2; // 2元买下一瓶啤酒
@Test
public void test(){
int init_money = 10;
int totalBeers = consume(init_money);
System.out.println(String.format("%d元钱,可以得到%d瓶啤酒", init_money, totalBeers));
}
private int consume(int money){
int beersByMoney = money / MONEY_TO_BEER;
System.out.println(String.format("用%d元钱,买下%d瓶啤酒,得到%d 个瓶盖和 %d 个瓶子",
money, beersByMoney, beersByMoney, beersByMoney));
return beersByMoney + exchange(beersByMoney, beersByMoney);
}
private int exchange(int caps, int bottles){
//当剩余的瓶盖数量和酒瓶数量都小于兑换基数时,就不能再兑换了。
if (caps < CAP_TO_BEER && bottles < BOTTLE_TO_BEER) return 0;
int byCap = caps / CAP_TO_BEER; // 用瓶盖兑换的啤酒
int byBottle = bottles / BOTTLE_TO_BEER; //用酒瓶兑换的啤酒
int totalExchangedBeers = byCap + byBottle; //瓶盖 和 酒瓶兑换的总共啤酒数量
//剩余的瓶盖数量(因为原有的瓶盖兑换完啤酒后,又得到了新的瓶盖,所以要加上得到的啤酒数量)
int remainingCaps = caps % CAP_TO_BEER + totalExchangedBeers;
int remainingBottles = bottles % BOTTLE_TO_BEER + totalExchangedBeers;
System.out.println(String.format("本次用 %d 个瓶盖和 %d 个瓶子兑换了 %d 瓶啤酒,剩余 %d 个瓶盖和 %d 个瓶子",
caps, bottles, totalExchangedBeers, remainingCaps, remainingBottles));
//返回的是本次兑换的啤酒数量加上剩余的瓶盖和瓶子能兑换的数量
return totalExchangedBeers + exchange(remainingCaps, remainingBottles);
}
}
以下是控制台的打印:
用10元钱,买下5瓶啤酒,得到5 个瓶盖和 5 个瓶子
本次用 5 个瓶盖和 5 个瓶子兑换了 3 瓶啤酒,剩余 4 个瓶盖和 4 个瓶子
本次用 4 个瓶盖和 4 个瓶子兑换了 3 瓶啤酒,剩余 3 个瓶盖和 3 个瓶子
本次用 3 个瓶盖和 3 个瓶子兑换了 1 瓶啤酒,剩余 4 个瓶盖和 2 个瓶子
本次用 4 个瓶盖和 2 个瓶子兑换了 2 瓶啤酒,剩余 2 个瓶盖和 2 个瓶子
本次用 2 个瓶盖和 2 个瓶子兑换了 1 瓶啤酒,剩余 3 个瓶盖和 1 个瓶子
10元钱,可以得到15瓶啤酒
因此,10元钱可以喝到15瓶啤酒。
群里面有人说,可以先拿下20瓶啤酒,然后就可以得到20个瓶盖和20个酒瓶,再用这些酒瓶和瓶盖去兑换啤酒,可以兑换到15瓶啤酒,然后把这15瓶啤酒还回去,这样就能表面上就只消费了20 - 15 = 5 瓶啤酒,两元一瓶,同样是10元。但是事实上消费了20瓶。对此,我只想说:你们城里人都这么会玩的吗??我还是好好敲代码吧。