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

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

相关推荐
he___H10 小时前
数据结构-移位
数据结构
云知谷11 小时前
【C++基本功】C++适合做什么,哪些领域适合哪些领域不适合?
c语言·开发语言·c++·人工智能·团队开发
电子_咸鱼11 小时前
LeetCode——Hot 100【电话号码的字母组合】
数据结构·算法·leetcode·链表·职场和发展·贪心算法·深度优先
仰泳的熊猫11 小时前
LeetCode:785. 判断二分图
数据结构·c++·算法·leetcode
rit843249911 小时前
基于MATLAB实现基于距离的离群点检测算法
人工智能·算法·matlab
my rainy days13 小时前
C++:友元
开发语言·c++·算法
haoly198913 小时前
数据结构和算法篇-归并排序的两个视角-迭代和递归
数据结构·算法·归并排序
微笑尅乐13 小时前
中点为根——力扣108.讲有序数组转换为二叉搜索树
算法·leetcode·职场和发展
小梁努力敲代码13 小时前
java数据结构--List的介绍
java·开发语言·数据结构
im_AMBER14 小时前
算法笔记 05
笔记·算法·哈希算法