如果一个三位数等于它的三个数字的立方和,那么该三位数称为水仙花数。例如: 153 = 1 ^ 3 + 5 ^ 3 + 3 ^ 3 371 = 3 ^ 3 + 7 ^ 3 + 1 ^ 3

求出所有的水仙花数。

水仙花数

问题描述

如果一个三位数等于它的三个数字的立方和,那么该三位数称为水仙花数。例如: 153 = 1 ^ 3 + 5 ^ 3 + 3 ^ 3 371 = 3 ^ 3 + 7 ^ 3 + 1 ^ 3

求出所有的水仙花数。

设计思路

通过一重循环穷举所有三位数 m。在穷举的过程中,将 m“分解”为百位、十位和个位对应的三 个数字 a、b 和 c,然后判断 m 是否等于 a、b 和 c 的立方和。

设置三位数的百位、十位和个位分别对应 a、b 和 c,通过三重循环穷举百位、十位和个位的三个 数字,其中,1<= a <= 9,0<= b <= 9,0<= c <= 9。在穷举的过程中,将 a、b 和 c“组合”为 三位数 m,然后判断 m 是否等于 a、b 和 c 的立方和。

Swift 3.0 代码实现

打印出所有的水仙花数(思路一:基于“分解”的程序设计)

func printAllNarcissisticNumbers1() {
    for m in 100...999 {
        let a = m / 100
        let b = (m / 10) % 10
        let c = m % 10
        
        if m == a * a * a + b * b * b + c * c * c {
            print(m)
        }
    }
}

print("所有水仙花数为:")
printAllNarcissisticNumbers1()

打印出所有的水仙花数(思路二:基于“组合”的程序设计)

func printAllNarcissisticNumbers2() {
    for a in 1...9 {
        for b in 0...9 {
            for c in 0...9 {
                let m = a * 100 + b * 10 + c
                
                if m == a * a * a + b * b * b + c * c * c {
                    print(m)
                }
            }
        }
    }
}

print("所有水仙花数为:")
printAllNarcissisticNumbers2()

算法理解

算法本身很容易理解:在3位数的情况下,穷举所有3位数,把1个数分为百、十、个,3个独立数,再根据水仙花数的定义,进行条件限制。或者,把3个独立1位数,组合为1个3位数,根据水仙花数的定义进行条件限制。注意,3个1位数,第1个,取值为1到9,后两个取值为0到9。

关键,在于 如何”分解“与”组合“。先说”组合“,3个数分别乘以100、10、1,再相加起来,就能得到1个3位数。再说”分解“:

let a = m / 100

3位数除以100,小数点左移两位,得到 个位.小数两位,Swift中,m是整型,a也会被推断为整型,小数的两位被舍去,得到百位数。

let b = (m / 10) % 10

3位数除以10,小数点左移1位,得到 两位.小数一位,再对10取余。m/10的中间值,已经舍去小数,所以,中间值是一个两位数。例如,如果中间值是88,对10取余,8个10+7,余数为8。从此,得到了原先那个3位数的十位数。

let c = m % 10

与上同理,例如,m=887时,887%10,88个10+7,余数为7.得到3位数的个位。