一、水仙花数
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;
}