自幂数(Narcissistic number)是编程竞赛和算法练习中的经典题型,也是初学者理解循环结构与数学运算的绝佳案例。这道来自洛谷B3841的题目要求我们判断一个给定的三位数是否为自幂数,即该数是否等于其各位数字的立方和。
在实际教学中,这类题目通常作为循环结构的入门练习。我注意到很多初学者在解决这个问题时容易陷入几个典型误区:比如错误处理输入范围、混淆数字位数提取方法、或者忽略边界条件验证。这道题虽然表面简单,但完整实现需要考虑以下几个关键点:
自幂数的数学本质是一个n位数,其值等于各位数字的n次幂之和。对于三位数而言,就是各位数字的立方和。例如153 = 1³ + 5³ + 3³ = 1 + 125 + 27,因此153是典型的三位自幂数。
在编程实现时,我们需要重点关注三个技术环节:
提取数字各位数有三种常见方法:
数学运算法(推荐):
字符串转换法:
python复制s = str(num)
hundreds = int(s[0])
tens = int(s[1])
units = int(s[2])
循环取余法:
python复制digits = []
while num > 0:
digits.append(num % 10)
num = num // 10
提示:在算法竞赛中,数学运算法通常效率最高且代码最简洁,是首选方案。
python复制def is_narcissistic(num):
# 输入验证
if not 100 <= num <= 999:
return False
# 分解数字
hundreds = num // 100
tens = (num // 10) % 10
units = num % 10
# 计算立方和
sum_of_cubes = hundreds**3 + tens**3 + units**3
# 判断是否为自幂数
return sum_of_cubes == num
# 测试用例
print(is_narcissistic(153)) # True
print(is_narcissistic(370)) # True
print(is_narcissistic(371)) # True
print(is_narcissistic(407)) # True
print(is_narcissistic(123)) # False
对于追求代码简洁性的开发者,可以使用以下实现:
python复制def is_narcissistic_short(num):
a, b, c = num//100, (num//10)%10, num%10
return num == a**3 + b**3 + c**3 if 100<=num<=999 else False
cpp复制#include <iostream>
using namespace std;
bool isNarcissistic(int num) {
if(num < 100 || num > 999) return false;
int a = num / 100;
int b = (num / 10) % 10;
int c = num % 10;
return num == a*a*a + b*b*b + c*c*c;
}
int main() {
cout << isNarcissistic(153) << endl; // 1 (true)
cout << isNarcissistic(123) << endl; // 0 (false)
return 0;
}
边界条件遗漏:
python复制# 错误示例:缺少输入范围检查
def is_narcissistic_bug1(num):
a, b, c = num//100, (num//10)%10, num%10
return num == a**3 + b**3 + c**3
数字分解错误:
python复制# 错误示例:十位数提取错误
def is_narcissistic_bug2(num):
a, b, c = num//100, num%100//10, num%10
return num == a**3 + b**3 + c**3
类型混淆错误:
python复制# 错误示例:字符串处理时忘记转换类型
def is_narcissistic_bug3(num):
s = str(num)
return num == s[0]**3 + s[1]**3 + s[2]**3
单元测试用例设计:
调试打印技巧:
python复制def debug_narcissistic(num):
a, b, c = num//100, (num//10)%10, num%10
print(f"分解结果:{a},{b},{c}")
print(f"立方和:{a**3}+{b**3}+{c**3}={a**3 + b**3 + c**3}")
return num == a**3 + b**3 + c**3
性能考量:
自幂数概念可以推广到任意位数:
通用判断函数实现:
python复制def is_narcissistic_general(num):
s = str(num)
n = len(s)
return num == sum(int(d)**n for d in s)
对于大规模查找自幂数的场景,可以考虑:
在实际教学中,我发现将数学概念与编程实践结合能显著提升学习效果。比如通过这个案例,学生可以同时掌握:
这个题目虽然简单,但很好地展示了如何将数学问题转化为算法实现的过程。我建议初学者在解决后可以尝试以下扩展练习: