现在有N元钱,两块钱一瓶,或者直接给你N瓶酒,两个空瓶换一瓶酒,四个瓶盖换一瓶酒,问你最后可以喝多少瓶?如果能借酒呢?
問題描述:現(xiàn)在有N元錢,兩塊錢一瓶,或者直接給你N瓶酒,兩個空瓶換一瓶酒,四個瓶蓋換一瓶酒,問你最后可以喝多少瓶?如果能借酒呢?
?
解決思路1:
N元錢,其實就是N/2瓶酒。所以我們在程序中直接使用N瓶酒進行計算,直接使用遞歸,直到最后余下的酒瓶和瓶蓋不夠換酒。但是要注意:每次換酒后可能會剩下酒瓶和瓶蓋,比如3個酒瓶和5個瓶蓋,拿出2個酒瓶和4個瓶蓋換完2瓶酒,剩下1個酒瓶和1個瓶蓋,需要“存”起來,可以和下一輪新增的酒瓶和瓶蓋一起換酒。代碼如下
import java.util.Scanner;public class Cnt_N_Beer { // 存儲每一次換完酒剩余的酒瓶和瓶蓋static int bottle = 0;static int cap = 0;static int beer(int n){ // 使用當(dāng)前的酒+酒瓶+瓶蓋計算可以換的酒int re_n = (bottle+n)/2 + (cap+n)/4;bottle = (bottle+n)%2;cap = (cap+n)%4; // 結(jié)束條件是換不了酒,那么直接返回,結(jié)束遞歸if(re_n == 0){return n;}return n+beer(re_n);}public static void main(String[] args) {Scanner user = new Scanner(System.in);System.out.print("please input an integer:");int n = user.nextInt();int beer_cnt; // 如果啤酒數(shù)量不夠兩瓶,沒得換,直接返回啤酒數(shù)量if((n<=1) && (n>=0)) {beer_cnt = n;bottle = n;cap = n;System.out.println("beer is " + beer_cnt); // 如果輸入的啤酒數(shù)量為負數(shù),提示}else if (n<0){System.out.println("beer count can't be negative");}else { // 使用beer方法遞歸計算beer_cnt = beer(n);System.out.println("beer is " + beer_cnt);} // 輸出最后剩余的酒瓶數(shù)和瓶蓋數(shù)System.out.println("bottle is " + bottle);System.out.println("cap is " + cap);} }?
幾個測試結(jié)果如下
? ????
?
不知道你有沒有發(fā)現(xiàn),不管酒的數(shù)量是多少,最后剩下的酒瓶都是1個,瓶蓋數(shù)是3個 ,等會第二種解決方案會用到這個性質(zhì)。那么我們是不是可以驗證一下,是不是真的每一次都會剩余1個酒瓶,3個瓶蓋?使用do_while循環(huán)驗證如下。
public class Cnt_N_Beer { // 存儲每一次換完酒剩余的酒瓶和瓶蓋static int bottle = 0;static int cap = 0;static int beer(int n){ // 使用當(dāng)前的酒+酒瓶+瓶蓋計算可以換的酒int re_n = (bottle+n)/2 + (cap+n)/4;bottle = (bottle+n)%2;cap = (cap+n)%4; // 結(jié)束條件是換不了酒,那么直接返回,結(jié)束遞歸if(re_n == 0){return n;}return n+beer(re_n);}public static void main(String[] args) {int n = 1;int loop = 500000;do{n++;beer(n);}while(((bottle==1) && (cap==3)) && (n<loop));System.out.println(n);} }?
?測試結(jié)果如下,每次都是因為達到了循環(huán)次數(shù)而退出,如果不加循環(huán)次數(shù)那么它會一直循環(huán)計算。說明每次運行beer()方法后都剩余1個酒瓶,3個瓶蓋。
?
解決思路2
? ? ? ? 兩個酒瓶換一瓶酒,四個瓶蓋可以換一瓶酒,然后一瓶酒是2元,所以一個瓶蓋的價值是5角,一個酒瓶的價值是1元,那么相當(dāng)于我們花5角錢就可以喝到一瓶酒,結(jié)果是這樣嗎,我們看一看如果是6元錢,首先可以買3瓶酒,根據(jù)思路1的運行結(jié)果,我們知道最后可以喝到7瓶酒,按照5角一瓶酒,6元錢我們不是可以喝12瓶酒嗎?哪里出問題了?
? ? ? ? 這里就要提到思路1中的最后一句話,每次最后都會剩下1個酒瓶和3個瓶蓋,所以我們是有2.5元浪費的,這2.5元換不了酒。所以每次計算需要先減去2.5元,然后再根據(jù)5角一瓶,計算最后可以喝多少酒?還要注意:如果錢是11.9,那么只能買5瓶酒,所以要先將輸入的浮點數(shù)轉(zhuǎn)為2的倍數(shù)的整數(shù),也就是說11.9變?yōu)?0,14.8變?yōu)?4,代碼如下
import java.util.Scanner;public class Money_N_Beer {public static void main(String[] args) {Scanner user = new Scanner(System.in);System.out.print("please input your money:");double real_money = user.nextDouble(); // 將輸入的浮點數(shù)轉(zhuǎn)為整數(shù),如11.9變成11int int_money = (int)real_money;/*** 雖然已經(jīng)是整數(shù),但是仍然會存在不夠買酒而多余1元,* 所以先除2得到能買酒的數(shù)量,然后再乘2轉(zhuǎn)為錢* 所以此時得到的money只會是偶數(shù) 0,2,4,6……*/int money = int_money/2*2;// 如果錢不夠2元,買不了酒if(money<2) {System.out.println("money is so little, can't buy beer"); // 如果money>=2 && money<4,那么只能買一瓶酒,最后不存在浪費2.5元,要特殊考慮}else if(money<4){System.out.println("beer is " + (money/2));System.out.println("bottle is " + (money/2));System.out.println("cap is " + (money/2));}else {int beer = (int)((money-2.5)/0.5);System.out.println("beer is " + beer);System.out.println("bottle is 1");System.out.println("cap is 3");}} }?
幾個測試結(jié)果如下
?
? ??
?
拓展:如果可以借酒呢?
這個是網(wǎng)頁上經(jīng)常看到的問題,按照我們上面的測試,不管多少瓶酒(大于1瓶酒),最后剩余的酒瓶都是1個,瓶蓋都是3個,如果可以借酒,借1瓶酒,那么喝完酒變?yōu)?個酒瓶,4個瓶蓋。可以換2瓶酒,酒喝完后有2個酒瓶,2個瓶蓋,可以用2個酒瓶接著換1瓶酒,喝完后剩余1個酒瓶,3個瓶蓋,結(jié)束。也就是借1瓶酒,我們可以喝4瓶酒,除去借的,我們可以多喝3瓶酒。如果可以一直借,那么可以一直喝下去。新增代碼如下紅色框代碼
?
?運行測試結(jié)果如下,每一次借酒都會增加3瓶酒
? ?
總結(jié)
以上是生活随笔為你收集整理的现在有N元钱,两块钱一瓶,或者直接给你N瓶酒,两个空瓶换一瓶酒,四个瓶盖换一瓶酒,问你最后可以喝多少瓶?如果能借酒呢?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中的与、或、非以及异或( | ~
- 下一篇: 什么是泛型,为什么要使用泛型? 泛型类和