关于水仙花数的拓展

一、水仙花数

1、什么是水仙花数

水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3 次幂之和等于它本身(例如:1 ^ 3 + 5 ^ 3+ 3 ^ 3 = 153)。

2、解决思路

显然,为了判断一个三位数 n 是否是水仙花数,需要先得到它的个位、十位和百位。具体的方法有很多,这里我通过 n 和10取模得到个位,n 除10再和10取模得到十位,n 除 100 得到百位。
得到个位十位百位后只需要判断他们的立方和是否等于 n ,就能知道 n 是不是水仙花数。

3、实现

这里我们只判断 num 是否是水仙花数。如果想判断多个数字只需要一个循环就可以解决,这里不再多说。

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int i, j, k, num;

	scanf("%d", &num);
	i = num % 10;
	j = num/10 % 10;
	k = num / 100;
	if(num == i*i*i + j*j*j + k*k*k)
	{
		printf("%d是水仙花数\n", num);
	}
	else
	{
		printf("%d不是水仙花数\n", num);
	}

	system("pause");
	return 0;
}	

二、自幂数

1、什么是自幂数

在上面我已经提过了水仙花数是自幂数的一种,以下是自幂数的定义。

自幂数是指一个 n 位数,它的每个位上的数字的 n 次幂之和等于它本身。(例如:当 n 为 3 时,有 1 ^ 3 + 5 ^ 3 + 3 ^ 3 = 153,153 即是 n 为 3 时的一个自幂数)
自幂数包括:独身数、水仙花数、四叶玫瑰数、五角星数、六合数、北斗七星数、八仙数、九九重阳数、十全十美数。

2、解决难点

显然,要求一个数 num 是否是自幂数,就需要先判断它的位数 n ,并把它的每一位取出来并判断它们的 n 次幂之和是否等于 num 。在这些操作中,首先就需要得到位数 n ,并根据 n 来计算后续的幂值。
那么,如何通过 n 来决定是使用几次幂呢?在这里,我使用了 if 语句来进行选择1

3、实现

在实现中,我定义了数组 num[N] 来保存所求数的每一位,N 定义为 3 。我们也可以将 N 定义为更大的数去求相应位数的自幂数2

#include<stdio.h>
#include<stdlib.h>

int main()
{
	int num[10], i, n, tmp;

	for (n = 0; n < 1000; n++)
	{
		tmp = n;
		for (i = 0; tmp != 0; tmp /= 10)
 		{
   			num[i] = tmp % 10;
   			i++;
  		}
  		if (1 == i)
  		{
  			if (n == num[0])
  			{
    				printf("%d是独身数\n", n);
   			}
   		}
   		else if(2 == i)
   		{
   			if(n == num[0] * num[0] + num[1] * num[1])
   			{
    				printf("%d是自幂数\n", n);
   			}
   		}
   		else if (3 == i)
  		{
  			if (n == num[0]*num[0]*num[0] + num[1]*num[1]*num[1] + num[2]*num[2]*num[2])
   			{
   				printf("%d是水仙花数\n", n);
   			}
   		}
   	}
   	
   	system("pause");
   	return 0;
   }		
   	

4、优化

上一步中我们初步实现了多位自幂数的判断,但是幂操作显得有些繁琐,我们还可以用 math.h 中带的 pow() 函数来求一个数的幂次,修改后如下:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

int main()
{
	int i, j, n, sum, num[10];
 	for (i = 0; i < 1000000; i++)
 	{
 		for (n = 0, j = i; j; j /= 10)
		{
			num[n] = j % 10;
			n++;
		}
		for (sum = 0, j = 0; j < n; j++)
		{
			sum += pow(num[j], n);
		}
		if (sum == i)
		{
			printf("%d\n", i);
		}
	}
	
	system("pause");
	return 0;
}


  1. switch 语句和 if 语句都能实现多选择结构,可以根据个人习惯进行选择。 ↩︎

  2. 注意:有符号位 int 的范围是 -2147483648—2147483647,无符号位 int 的范围是 0—4294967295,能实现部分 10 位自幂数的计算。使用高精度计算,可以得到超过 int 类型上限的自幂数。 ↩︎

猜你喜欢

转载自blog.csdn.net/shiawaseli/article/details/88643550