10元最多可喝多少瓶啤酒?(不可借酒+可借酒)

背景

《愛情公寓5》中有個劇情:每瓶啤酒2元,2個空酒瓶或4個瓶蓋可換1瓶啤酒。10元最多可喝多少瓶啤酒?
腦海模擬起來的確有點費勁。心算結果是15瓶,而劇情實踐竟然是20瓶!結合彈幕說的酒吧可能能夠借酒,故猜想借酒使最終喝了20瓶。
若是改變擁有的錢數或啤酒價格時,答案又是什麼呢?
此時,不由想用編程的方法解決一下。編程

思路

分兩種狀況:酒吧能夠借酒;酒吧不能夠借酒;swift

酒吧不能夠借酒

此時,當剩餘酒蓋數<4且剩餘空瓶數<2時,計算就結束了code

酒吧能夠借酒

這種狀況比較麻煩,須要考慮1個空瓶和3個瓶蓋時借一瓶酒的狀況。此時,當換完酒、假設喝了酒並把酒瓶換新酒、喝了新酒以後(空瓶1,瓶蓋3),手上的酒瓶和酒蓋的價值不大於已借的酒瓶數(2瓶)時,就須要考慮結束計算了。
詳細代碼以下:get

//
//  main.swift
//  beerMaxDrink
//
//  Created  on 2020/2/4.
//  Copyright © 2020. All rights reserved.
//
/*
 酒吧啤酒2元一瓶,兩個空瓶或四個瓶蓋能夠換一瓶啤酒(酒吧概不借酒),你有10元錢,請問最多能夠喝幾瓶?
 */

import Foundation

//共累計喝的瓶數
var drinkSum = 0
//當前瓶子數
var bottleNum = 0
//當前瓶蓋數
var capsNum = 0

//返回(累計喝瓶數,剩餘瓶子數,剩餘瓶蓋數)
func getMaxDrinkSum(money:Float, price:Float) ->(Int, Int, Int) {

    bottleNum = Int(money / price)
    capsNum = bottleNum
    drinkSum = bottleNum
    
    //開始換酒,是個循環
    while bottleNum > 1 || capsNum > 3 {
        //酒瓶換
        let wineAddedByBottle = bottleNum / 2
        drinkSum += wineAddedByBottle
        bottleNum = bottleNum % 2 + wineAddedByBottle
        capsNum += wineAddedByBottle
        
        //酒蓋換
        let wineAddedByCaps = capsNum / 4
        drinkSum += wineAddedByCaps
        capsNum = capsNum % 4 + wineAddedByCaps
        bottleNum += wineAddedByCaps
    }
    return (drinkSum, bottleNum, capsNum)
}

//能夠借酒時,返回(累計喝瓶數,剩餘瓶子數,剩餘瓶蓋數)
func getMaxDrinkSumCanBorrow(money:Float, price:Float) ->(Int, Int, Int) {

    var borrowedNum = 0
    bottleNum = Int(money / price)
    capsNum = bottleNum
    drinkSum = bottleNum
    
    //開始換酒,是個循環
    while bottleNum >= 1 || capsNum >= 3 {
 
        //酒瓶換
        let wineAddedByBottle = bottleNum / 2
        drinkSum += wineAddedByBottle
        bottleNum = bottleNum % 2 + wineAddedByBottle
        capsNum += wineAddedByBottle
        
        //若是(2酒瓶2酒蓋時,"酒瓶換"已經把2酒瓶換爲1瓶1蓋,即變爲1瓶3蓋,方便作判斷)借一瓶後,空瓶和瓶蓋能換的酒數 <= 已借瓶數時,結束;不然,借一瓶
        if 1 == bottleNum || 3 == capsNum{//不能少,不然在循環時會提早借酒
            if (bottleNum + 1)/2 + (capsNum + 1)/4 <= borrowedNum {
                
                //不該該喝一瓶,回退
                bottleNum += 1
                capsNum -= 1
                return (drinkSum - 1, bottleNum - borrowedNum, capsNum - borrowedNum)
            }else{ //借一瓶
                borrowedNum += 1
                bottleNum += 1
                capsNum += 1
                
                //酒瓶換
                let wineAddedByBottle = bottleNum / 2
                drinkSum += wineAddedByBottle
                bottleNum = bottleNum % 2 + wineAddedByBottle
                capsNum += wineAddedByBottle
            }
        }
        
        //酒蓋換
        let wineAddedByCaps = capsNum / 4
        drinkSum += wineAddedByCaps
        capsNum = capsNum % 4 + wineAddedByCaps
        bottleNum += wineAddedByCaps
    }
    return (drinkSum, bottleNum, capsNum)
}

let rslt0 = getMaxDrinkSum(money: 10.0, price: 2)
print(rslt0)

let rsltCanBorrow0 = getMaxDrinkSumCanBorrow(money: 10.0, price: 2)
print(rsltCanBorrow0)

let rslt1 = getMaxDrinkSum(money: 10.0, price: 5)
print(rslt1)

let rsltCanBorrow1 = getMaxDrinkSumCanBorrow(money: 10.0, price: 5)
print(rsltCanBorrow1)

運行結果以下,證實代碼正確:it

(15, 1, 3)
(20, 0, 0)
(3, 1, 3)
(8, 0, 0)
Program ended with exit code: 0
相關文章
相關標籤/搜索