水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
(结尾无空行)
输出样例:
153
370
371
407
(结尾无空行)
难点分析:
相信能来博客中查询的好朋友们基本上都是由于最后一个案例(N = 7)运行超时而来的,其主要原因在程序的执行过程中有很多的pow()运算,而绝大部分的pow()运算是个位数(0~9)的同次幂运算,我们在运算可以将个位数幂运算的结果缓存起来,就可以加快程序的执行了,利用空间换时间。
程序代码:
#include <stdio.h>
#include <math.h>
// 对于10以内的幂运算进行缓存,加快运算。
int cache_pow[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int pow_Dicache(int x, int n)
{
// 不在0~9之间,调用库函数pow
if (x >= 10 || x < 0)
return pow(x, n);
// 数据已经缓存,直接取出
if (cache_pow[x] != -1)
return cache_pow[x];
// 数据未缓存,计算并缓存
cache_pow[x] = pow(x, n);
return cache_pow[x];
}
int isPercet(int k, int N) //判断是否为水仙花数
{
int sum = 0, a = k;
while (a)
{
int t = a % 10;
sum += pow_Dicache(t, N); //此处是对数字最后一位进行运算,故采用带缓存的幂运算。
a = a / 10;
if(sum > k)
return 0;
}
return k == sum ? 1 : 0;
}
int main(void)
{
int N;
scanf("%d", &N);
for (int i=pow_Dicache(10, N-1), top=pow_Dicache(10, N)-1; i<=top; i++)
{
if (isPercet(i, N))
{
printf("%d\n", i);
}
}
return 0;
}
后记:
No Pains,No Gains.
感谢@Wwlllr大佬博客(习题4-6 水仙花数 (20 分)_Wwlllr的博客-CSDN博客)思路灵感。