您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页Swift - 猴子分桃问题

Swift - 猴子分桃问题

来源:二三四教育网

题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?

这是采用试探法,由少到多逐渐试探。由题意知,原来的桃子肯定多于 6 个,所以这里由 6 开始,逐渐增加桃子数目,直到 5 只猴子第一次全部分桃成功,则得到的结果就是最少的满足条件的数量。

程序流程图

程序:

// 桃总数
var peachAmount = 6
// 剩下的桃的数量
var leftPeachs = 0
// 循环结束标志
var loopVoer = false

while !loopOver {
    leftPeachs = peachAmount
    for i in 1...5 {
        if (leftPeachs - 1) % 5 == 0 {
            leftPeachs = 4 * (leftPeachs - 1) / 5
            if i == 5 {
                // 达到 5 次,试探成功,设置 loopOver 为真以退出 while 循环
                loopOver = true
            }
        } else {
            // 试探失败,增加桃子数量,退出 for in 循环,重新开始
            peachAmount += 1
            break
        }
    }
}

得到的结果为,原来的桃子数量最少为 3121 个,分完后还剩 1020 个
上面增加桃子数量时,每次只加 1 ,步长值太小。其实因为要被 5 整除,所以可以每次加 5 的。所以增加数量部分可以写成这样:

 peachAmount += 5

这样可以减少很多无用功。
其实,可以进一步分析得出,失败于第 2 只猴子时,增加的数量应能被 5(5的1次方) 整除;失败于第 3 只猴子时,增加的数量应能被 25(5的2次方) 整除,以此类推。所以增加数量部分可以进一步写成这样:

 peachAmount += Int(pow(Double(5), Double(i - 1)))

这样可以最大限度地降低试探次数。

下面的代码除了作增加数量上的修改,还增加了一个 monkeyAmount(猴子数量) 常量,这样可以使代码更通用一些。比如你测试不同数量的猴子时,只需改这个常量值就可以了。

loopVoer = false
let monkeyAmount = 9
peachAmount = monkeyAmount + 1
while !loopOver {
    leftPeachs = peachAmount
    for i in 1...monkeyAmount {
        if (leftPeachs - 1) % monkeyAmount == 0 {
            leftPeachs = (monkeyAmount - 1) * (leftPeachs - 1) / monkeyAmount
            if i == monkeyAmount {
                loopOver = true
            }
        } else {
            peachAmount += Int(pow(Double(monkeyAmount), Double(i - 1)))
            break
        }
    }
}

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务