啊哈c语言——逻辑挑战9:水仙花数

有一种三位数特别奇怪,这种数的"个位数的立方"加上"十位数的 立方"再加上"百位数的立方"恰好等于这个数。例如: 153=1×1×1+5×5×5+3×3×3,我们为这种特殊的三位数起了一个很好听的名字------"水仙花数",那么请你找出所有的"水仙花数"吧。

来分析一下,既然这个数是三位数,那么必然是100~999中的数。 所以我们只需将所有可能性的组合一一判断就可以了。进一步分析,这个三位数的百位上只可能是1~9,十位上只可能是0~9,个位上只可能是0~9。

我们用三重嵌套循环来产生100~999,代码如下:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main( )
{
    int i, j, k;
    for(i=1; i<=9; i++)
    {
        for(j=0; j<=9; j++)
        {
            for(k=0; k<=9; k++)
            {
                printf("%d ", i*100+j*10+k);
            }
        }
    }
    system("pause");
    return 0;
}

在上面的代码中,我们用for循环i来表示这个三位数的百位(从1循 环到9),用for循环j来表示这个三位数的十位(从0循环到9),用for循 环k来表示这个三位数的个位(从0循环到9)。然后用百位上的数乘以100加上十位上的数乘以10再加上个位上的数就组成了这个三位数,即 i×100+j×10+k。怎么样?运行了上面的代码后计算机是不是输出了100 ~999呢。

接下来的问题就简单了,来判断这个数是否符合"水仙花数"的要求 就可以了。我们只需在打印之前通过if语句来判断一下就可以了。

cpp 复制代码
if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
        printf("%d ", i*100+j*10+k);

完整的代码如下:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main( )
{
    int i, j, k;
    for(i=1; i<=9; i++)
    {
        for(j=0; j<=9; j++)
        {
            for(k=0; k<=9; k++)
            {
                if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                {
                    printf("%d ", i*100+j*10+k);
                }
            }
        }
    }
    system("pause");
    return 0;
}

其实,上面的代码可以简写为:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main( )
{
    int i, j, k;
    for(i=1; i<=9; i++)
    for(j=0; j<=9; j++)
    for(k=0; k<=9; k++)
    if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
    printf("%d ", i*100+j*10+k);
    system("pause");
    return 0;
}

因为在for循环i中只嵌套了一个for循环j, for循环j中也只嵌套了一个 for循环k, for循环k中只有一个if语句,if语句中只有一个printf语句,因 此所有{ }都可以省略。

怎么样?做出来没有?"水仙花数"只有4个,分别是153、370、371 和407。

上面的方法是"拼接法",即分别枚举百位、十位、个位上的数的所 有可能,然后再拼接成一个3位数(百位×100+十位×10+个位)。其实我们还可以使用分割法,即将一个三位数x拆分成3部分,即a、b、c, 分别用来存放百位、十位、个位上的数。如果 a×a×a+b×b×b+c×c×c==x,就说明这个数是"水仙花数"。

那现在的问题是怎样把x拆分成a、b、c呢?例如,当x等于123的时 候,让a里面存1, b里面存2, c里面存3。

对于一个三位数该怎么获取它的个位上的数呢?很简单,只需将这 个数除以10求余数就可以了。

那怎么获得百位上的数呢?也很简单,只需将这个数除以100就可以了。因为在C语言中,如果"/"号的左右两边都只有整数部分的话,那么"商"也只有整数部分。

获得十位上的数有点麻烦,过程如下:

先将这个数除以10,去除个位,让原来的十位变成个位 (123/10→12),然后再除以10求余数就可以了(12/10→2)。

转换为C语言代码:

试一试看吧:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main( )
{
    int x, a, b, c;
    x=123;
    a=x/100;
    b=x/10%10;
    c=x%10;
    printf("%d %d %d", a, b, c);
    system("pause");
    return 0;
}

怎么样?是不是成功地分离出来啦。下面,我们只需让x在100~ 999内循环就可以了:

cpp 复制代码
for(x=100; x<=999; x++)
{
}

最后加上"水仙花数"的判断:

cpp 复制代码
if(x==a*a*a+b*b*b+c*c*c)
printf("%d ", x);

完整的代码如下:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main( )
{
    int x, a, b, c;
    for(x=100; x<=999; x++)
    {
        a=x/100;
        b=x/10%10;
        c=x%10;
        if(x==a*a*a+b*b*b+c*c*c)
        printf("%d ", x);
    }
    system("pause");
    return 0;
}

其实我们可以将

cpp 复制代码
a=x/100;
b=x/10%10;
c=x%10;

改为:

cpp 复制代码
a=x/100%10;
b=x/10%10;
c=x/1%10;

效果不变!有没有看出什么奥妙?自己去想吧!

相关推荐
侯小啾2 小时前
【03】C语言 强制类型转换 与 进制转换
c语言·数据结构·算法
Xの哲學3 小时前
Linux NAPI 架构详解
linux·网络·算法·架构·边缘计算
云知谷3 小时前
【经典书籍】C++ Primer 第15章类虚函数与多态 “友元、异常和其他高级特性” 精华讲解
c语言·开发语言·c++·软件工程·团队开发
京东零售技术6 小时前
扛起技术大梁的零售校招生们 | 1024技术人特别篇
算法
爱coding的橙子7 小时前
每日算法刷题Day78:10.23:leetcode 一般树7道题,用时1h30min
算法·leetcode·深度优先
Swift社区7 小时前
LeetCode 403 - 青蛙过河
算法·leetcode·职场和发展
地平线开发者7 小时前
三种 Badcase 精度验证方案详解与 hbm_infer 部署实录
算法·自动驾驶
papership7 小时前
【入门级-算法-5、数值处理算法:高精度的减法】
算法·1024程序员节
lingran__7 小时前
算法沉淀第十天(牛客2025秋季算法编程训练联赛2-基础组 和 奇怪的电梯)
c++·算法
DuHz7 小时前
基于MIMO FMCW雷达的二维角度分析多径抑制技术——论文阅读
论文阅读·物联网·算法·信息与通信·毫米波雷达