• 10元最多可喝多少瓶啤酒?(不可借酒+可借酒,swift语言实现)


    背景

    《爱情公寓5》中有个剧情:每瓶啤酒2元,2个空酒瓶或4个瓶盖可换1瓶啤酒。10元最多可喝多少瓶啤酒?
    脑海模拟起来的确有点费劲。心算结果是15瓶,而剧情实践居然是20瓶!结合弹幕说的酒吧可能可以借酒,故猜测借酒使最终喝了20瓶。
    如果改变拥有的钱数或啤酒价格时,答案又是什么呢?
    此时,不禁想用编程的方法解决一下。

    思路

    分两种情况:酒吧可以借酒;酒吧不可以借酒;

    酒吧不可以借酒

    此时,当剩余酒盖数<4且剩余空瓶数<2时,计算就结束了

    酒吧可以借酒

    这种情况比较麻烦,需要考虑1个空瓶和3个瓶盖时借一瓶酒的情况。此时,当换完酒、假设喝了酒并把酒瓶换新酒、喝了新酒之后(空瓶1,瓶盖3),手上的酒瓶和酒盖的价值不大于已借的酒瓶数(2瓶)时,就需要考虑结束计算了。
    详细代码如下:

    //
    //  main.swift
    //  beerMaxDrink
    //
    //  Created by 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)
    }
    
    for i in 0..<20{
        let rslt0 = getMaxDrinkSum(money: Float(i), price: 2)
        print("-----------------------")
        print("(i)元:不能借酒:(rslt0)")
    
        let rsltCanBorrow0 = getMaxDrinkSumCanBorrow(money: Float(i), price: 2)
        print("能借酒:(rsltCanBorrow0)")
    }
    
    let rslt1 = getMaxDrinkSum(money: 10.0, price: 5)
    
    print("-----------------------")
    print("酒价格5元时,不能借酒:(rslt1)")
    
    let rsltCanBorrow1 = getMaxDrinkSumCanBorrow(money: 10.0, price: 5)
    print("能借酒:(rsltCanBorrow1)")
    
    

    运行结果如下,证明代码正确。且可以看出规律:可以借酒时,一般比不能借酒时,可以多喝5瓶酒:

    -----------------------
    0元:不能借酒:(0, 0, 0)
    能借酒:(0, 0, 0)
    -----------------------
    1元:不能借酒:(0, 0, 0)
    能借酒:(0, 0, 0)
    -----------------------
    2元:不能借酒:(1, 1, 1)
    能借酒:(4, 0, 0)
    -----------------------
    3元:不能借酒:(1, 1, 1)
    能借酒:(4, 0, 0)
    -----------------------
    4元:不能借酒:(3, 1, 3)
    能借酒:(8, 0, 0)
    -----------------------
    5元:不能借酒:(3, 1, 3)
    能借酒:(8, 0, 0)
    -----------------------
    6元:不能借酒:(7, 1, 3)
    能借酒:(12, 0, 0)
    -----------------------
    7元:不能借酒:(7, 1, 3)
    能借酒:(12, 0, 0)
    -----------------------
    8元:不能借酒:(11, 1, 3)
    能借酒:(16, 0, 0)
    -----------------------
    9元:不能借酒:(11, 1, 3)
    能借酒:(16, 0, 0)
    -----------------------
    10元:不能借酒:(15, 1, 3)
    能借酒:(20, 0, 0)
    -----------------------
    11元:不能借酒:(15, 1, 3)
    能借酒:(20, 0, 0)
    -----------------------
    12元:不能借酒:(19, 1, 3)
    能借酒:(24, 0, 0)
    -----------------------
    13元:不能借酒:(19, 1, 3)
    能借酒:(24, 0, 0)
    -----------------------
    14元:不能借酒:(23, 1, 3)
    能借酒:(28, 0, 0)
    -----------------------
    15元:不能借酒:(23, 1, 3)
    能借酒:(28, 0, 0)
    -----------------------
    16元:不能借酒:(27, 1, 3)
    能借酒:(32, 0, 0)
    -----------------------
    17元:不能借酒:(27, 1, 3)
    能借酒:(32, 0, 0)
    -----------------------
    18元:不能借酒:(31, 1, 3)
    能借酒:(36, 0, 0)
    -----------------------
    19元:不能借酒:(31, 1, 3)
    能借酒:(36, 0, 0)
    -----------------------
    酒价格5元时,不能借酒:(3, 1, 3)
    能借酒:(8, 0, 0)
    Program ended with exit code: 0
    
    学无止境,快乐编码。 没有一种不经过蔑视、忍受和奋斗就可以征服的命运。
  • 相关阅读:
    MySQL在大数据Limit使用
    debian非正常关机进不了图形界面的解决方法
    debian 系统备份
    数据库对内存的存储与读取
    QT: QByteArray储存二进制数据(包括结构体,自定义QT对象)
    Mysql数据库备份和按条件导出表数据
    QTableWidget控件总结
    Mysql数据库导入命令Source详解
    Mysql数据库导出压缩并保存到指定位置备份脚本
    Mysql导出表结构及表数据 mysqldump用法
  • 原文地址:https://www.cnblogs.com/Dast1/p/12262231.html
Copyright © 2020-2023  润新知