习题4-6 水仙花数 (20 分)

水仙花数是指一个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博客)思路灵感。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值