FreedomLy's blog.

【每周一坑】阿姆斯特朗数

字数统计: 528阅读时长: 2 min
2017/08/04 Share

armstrong
快一个月没写博客了,整个七月确实比较忙,也没什么时间弄管理博客(虽然就我一个人会看这个Blog…),今天诈尸更新一下~~

一个经典的编程练习题:

如果一个n位正整数等于其各位数字的n次幂之和,则称该数为阿姆斯特朗数(亦称为自恋数、自幂数)。
如 $407 = 4^3 + 0^3 + 7^3$ 就是一个阿姆斯特朗数

问题

输出1000以内的所有阿姆斯特朗数。

附加题

输入一个整数,输出距离它最近的阿姆斯特朗数。

思路

一眼看到阿姆斯特朗就想到了《银魂》阿姆斯特朗回旋加速喷气式阿姆斯特朗炮了,果然银魂毁节操QAQ。

回到主题,其实阿姆斯特朗数和水仙花数差不多。
满足阿姆斯特朗数的公式如下,设 $ n = d_kd_{k-1}\cdots d_1 $,则有

$$
n = d_k^k + d_{k-1}^k+\cdots+d_2^k+d_1^k
$$

编写代码是只要得到整数n的各个位上的数,然后进行k次幂求和即可。

1
2
3
4
5
6
7
8
temp = num
while temp:
# 求出每位数的k次幂的和
res += (temp % 10)**n
num //= 10
if res == num:
# 如果满足阿姆斯特朗数的条件,就返回这个数
return num

Python实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# -*- coding: utf-8 -*-


# 得到bound以内的阿姆斯特朗数,bound默认为1000
def get_number(bound=1000):
armstrong_number = []
for i in range(bound):
temp = i
n = len(str(i))
res = 0
while temp:
res += (temp % 10) ** n
temp //= 10
if res == i:
armstrong_number.append(i)
return armstrong_number


# 得到离number最近的阿姆斯特朗数
def get_nearest_number(num):
if is_arm_num(num):
return num
temp = num
res = get_number(temp)[-1]
while not is_arm_num(temp):
temp += 1
res_new = temp
if abs(res_new - num) < abs(res - num):
return res_new
else:
return res


# 判断num是否是阿姆斯特朗数
def is_arm_num(num):
temp = num
res = 0
n = len(str(num))
while temp:
res += (temp % 10) ** n
temp //= 10
return res == num


if __name__ == '__main__':
print(get_number())
print(get_nearest_number(390))
print(get_nearest_number(389))

测试

输出结果

1
2
3
4
5
6
7
8
>>> get_number(1000)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407]

>>> get_nearest_number(390)
407

>>> get_nearest_number(389)
371

满足问题要求

参考资料

[1]: Wiki 水仙花数

End~


CATALOG
  1. 1. 问题
  2. 2. 思路
  3. 3. Python实现
  4. 4. 测试
  5. 5. 参考资料