啊哈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;

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

相关推荐
小刘|29 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou34 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
xinghuitunan1 小时前
蓝桥杯顺子日期(填空题)
c语言·蓝桥杯
van叶~1 小时前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
Half-up1 小时前
C语言心型代码解析
c语言·开发语言
简简单单做算法1 小时前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
云卓SKYDROID1 小时前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
懒大王就是我1 小时前
C语言网络编程 -- TCP/iP协议
c语言·网络·tcp/ip
半盏茶香1 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童2 小时前
双指针算法习题解答
算法