「题目讲解」C语言 使用函数判断水仙花数 求范围内的所有水仙花数

题目内容

  1. 写两个函数
  2. 函数narcissistic,传入一个值,用于判断输入的数是不是水仙花数,是水仙花数返回1,否则返回0
  3. 函数PrintN,传入两个值,求开区间范围内所有水仙花数

注1:题目中保证100≤m≤n≤10000
注2: 水仙花数:一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身
eg: 153 = 1 * 1 * 1 + 5 * 5 * 5 + 3 * 3 * 3

测试程序样例

#include <stdio.h>

int narcissistic( int number );
void PrintN( int m, int n );

int main()
{
    int m, n;

    scanf("%d %d", &m, &n);
    if ( narcissistic(m) ) printf("%d is a narcissistic number\n", m);
    PrintN(m, n);
    if ( narcissistic(n) ) printf("%d is a narcissistic number\n", n);

    return 0;
}

在程序后面完成自己的函数

输入样例

153 400

输出样例

153 is a narcissistic number
370
371

注 题目来源:浙大版《C语言程序设计(第3版)》题目集

解题思路

观察题目,输入和输出样例,可知printN函数的两端是开区间,会帮我们判断两端是否是水仙花数,且数字后有"is a narcissistic number",我们的函数只需输出数字
再观察程序头部和主函数,printN函数的类型是void,主函数中也没有关于printN的输出语句,因此我们的printN函数不需要return,而是在函数中直接输出
我们可以通过在printN函数中调用narcissistic函数,将所有结果是1的数进行输出来完成寻找水仙花数
而narcissistic函数需要我们把一个三位数或者四位数的每一位拆开进行,进行幂运算,判断这个数是不是水仙花数,而要把每一个数拆开,我们要先判断这个数是几位数

柿子挑软的捏(doge),所以咱可以先写printN函数

void PrintN( int m, int n )
{
  int i;
  for(i=m+1;i<n;i++)
  {
    if ( narcissistic( i ) ) {
      printf("%d\n", i);
    }
  }
}

只需要一个for循环和一个嵌套着narcissistic函数的if语句就可以搞定
因为调用了narcissistic函数,所以我们的narcissistic函数要放在printN函数的上面,按照刚才的思路,我们先判断数字是几位数,然后按照不同的位数分类讨论取出每一位数,之后进行判断输出。好在题目中给了我们m和n的范围,最大是10000,用脚趾算一下就可以知道这不是水仙花数,所以我们只需要判断这个数是三位数或者四位数就可以了
需要注意的是在头文件中我们没有调用math.h库,所以函数里不能使用pow()函数

int narcissistic( int number)
{
  int i = 1,result = 0;
  int number1 = number;
  //这里用到number1的原因是下面while循环做位数判断的时候
  //要一个number进行自除,之后还需要一个number进行判断
  int a = 0, b = 0, c = 0, d = 0;
  while (number1 >= 10 ) {
    number1 /= 10;
    i += 1;
  }
  //上面用于判断一个数字有几位数
  if (i == 3) {
    a = number % 10;
    b = number / 10 % 10;
    c = number / 100;
    if (number == a*a*a+b*b*b+c*c*c) {
      result = 1;
    }
  }
  if (i == 4) {
    a = number % 10;
    b = number / 10 % 10;
    c = number / 100 % 10;
    d = number / 1000;
    if (number == a*a*a*a+b*b*b*b+c*c*c*c+d*d*d*d) {
      result = 1;
  }
}
return result;
}

看一下结果

输入:

153 400

输出:

153 is a narcissistic number
370
371

没有问题!!!

方法优化

今天早上起来又看到这道题,仔细一想,这段代码(特别是narcissistic函数)有很多可以优化的地方,比如虽然头文件中没有给出<math.h>库,但我i们可以尝试在函数的上面自己加入<math.h>库

#include <math.h>

int narcissistic( int number)

像这样
还有就是在判断一个数字是几位数的时候,完全没必要像我一开始那样小题大做,用一个while循环来判断这个数字是几位数,极大的提升了这道题的时间复杂度,因为题目保证了最大数字是10000,最小的水仙花数也是三位数,所以我们只要用两个if语句就可以把三位数和四位数分别处理,修改后代码如下:

#include <stdio.h>

int narcissistic( int number );
void PrintN( int m, int n );

int main()
{
    int m, n;

    scanf("%d %d", &m, &n);
    if ( narcissistic(m) ) printf("%d is a narcissistic number\n", m);
    PrintN(m, n);
    if ( narcissistic(n) ) printf("%d is a narcissistic number\n", n);

    return 0;
}

#include <math.h>

int narcissistic( int number)
{
  int i = 1,result = 0;
  int a = 0, b = 0, c = 0, d = 0;
  if (number>=100 && number < 1000) {
    a = number % 10;
    b = number / 10 % 10;
    c = number / 100;
    if (number==pow(a,3)+pow(b,3)+pow(c,3)) {
      result = 1;
    }
  }
  if (number>=1000 && number < 10000) {
    a = number % 10;
    b = number / 10 % 10;
    c = number / 100 % 10;
    d = number / 1000;
    if (number==pow(a,4)+pow(b,4)+pow(c,4)) {
      result = 1;
    }
  }
return result;
}

void PrintN( int m, int n )
{
  int i;
  for(i=m+1;i<n;i++)
  {
    if ( narcissistic( i ) ) {
      printf("%d\n", i);
    }
  }
}

narcissistic函数比之前少了近10行代码!!

总结

收获的知识:
调用的库不一定要卸写在文件的最上面,写在函数的最上面也能正常运行
在数字范围差别不大的情况下,用if语句代替while循环效率会更高
希望能帮到大家!!

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值