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

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

相关推荐
Han.miracle5 分钟前
数据结构与算法--006 和为s的两个数字(easy)
java·数据结构·算法·和为s的两个数字
AuroraWanderll18 分钟前
C++类和对象--访问限定符与封装-类的实例化与对象模型-this指针(二)
c语言·开发语言·数据结构·c++·算法
white-persist19 分钟前
网络空间安全核心领域技术架构深度解析
c语言·开发语言·网络·python·安全·网络安全·架构
月明长歌21 分钟前
【码道初阶】LeetCode 622:设计循环队列:警惕 Rear() 方法中的“幽灵数据”陷阱
java·算法·leetcode·职场和发展
秦苒&22 分钟前
【C语言指针三】一维数组传参的本质、冒泡排序、二级指针、指针数组、指针数组模拟二维数组、字符指针变量
c语言·开发语言
Dylan的码园22 分钟前
链表与LinkedList
java·数据结构·链表
走错路的程序员28 分钟前
C语言单片机与C#上位机之间传递大量参数比较好的实践方案
c语言·单片机·c#
mit6.82428 分钟前
博弈-翻转|hash<string>|smid
算法
代码游侠31 分钟前
复习——Linux 系统编程
linux·运维·c语言·学习·算法
Han.miracle38 分钟前
优选算法-005 有效三角形的个数(medium)
数据结构·算法·有效的三角形个数