什么是水仙花数?
“水仙花数”是指一个n位数,其各位数字的 n 次方之和确好等于该数本身,
如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
解题思路
1:输入一个整形(或者循环),求出他的位数 n ;
2:获取整形中每个位置上的数据,并对其进行立方求和;
3:判断此立方和是否与远来的整形相等;
4:相等则打印,不等则忽略。
整体框架:
#include<stdio.h>
int main()
{
int arr[6];
for (int i = 0; i <= 100000; i++)
{
int k = i;
int n = weishu(i);
pan_duan(i, k, n, arr);//n=2 i=10
}
return 0;
}
这里的数组 arr [ 6 ] 是用来接收后面 整形拆分后的每一位数。
weishu()函数 则是来判断并返回 整形的位数 且用 n 接收;
pan_duan()函数时用来判断是否为水仙花数的过程。
(为了增加其可读性,次方求和将被放入 pan_duan()函数当中执行)
函数的实现:
1、weishu()函数, 位数 n 以 count 计数来完成。
int weishu(int a)//计算整形位数
{
int count = 0;
if (a == 0)
{
count = 1;
}
while (a != 0)
{
a = a / 10;
count++;
}
return count;
}
2、pan_duan()函数实现:
void pan_duan(int a, int k, int n, int *arr) //a=10; k=10; n=2;
{
for (int i = (n - 1); i >= 0; i--)
{
*(arr + i) = a % 10;
a /= 10;
}
int p = 0;
for (int i = 0; i < n; i++)
{
int ret = mi(*(arr + i),n);
p += ret;
}
if (p == k)
printf("%d ", k);
}
其中 mi() 函数为求整形数位的 n 次方求和;这里不直接在pan_duan函数里面计算式因为里面关于n的数位--操作符会影响到当次循环当中的 i<n 当中的 n,会直接影响到打印结果。
这里简单粘贴一个图片方便理解;
mi() 函数实现:
int mi(int v,int m)//计算单个数字的数位次方
{
int b = 1;
while (m != 0)
{
b *= v;
--m;
}
return b;
}
最后完整的代码:
#include<stdio.h>
int weishu(int a)//计算整形位数
{
int count = 0;
if (a == 0)
{
count = 1;
}
while (a != 0)
{
a = a / 10;
count++;
}
return count;
}
int mi(int v,int m)//计算单个数字的数位次方
{
int b = 1;
while (m != 0)
{
b *= v;
--m;
}
return b;
}
void pan_duan(int a, int k, int n, int *arr) //判断是否为水仙花数并打印
{
for (int i = (n - 1); i >= 0; i--)
{
*(arr + i) = a % 10;
a /= 10;
}
int p = 0;
for (int i = 0; i < n; i++)
{
int ret = mi(*(arr + i),n);//函数实现整形位数的n次方和
p += ret;
}
if (p == k)
printf("%d ", k);
}
int main()
{
int arr[6];
for (int i = 0; i <= 100000; i++)//循环判断0~100000的水仙花数
{
int k = i;
int n = weishu(i);
pan_duan(i, k, n, arr);//n=2 i=10
}
return 0;
}
运行结果:![](https://i-blog.csdnimg.cn/blog_migrate/d41a5b1a15102529814ae85bf79a9c37.png)
算法优化:
这里面求次方和其实可以用 pow()库函数 来解决。
不过在使用的时候用的是一个整形接收pow()的返回值,这里可以强制类型转换 (int)pow()。
此外 计算数位 n的函数也可以优化为:
while(i/10)
{
count++;
i = i/10;
}
总得下来优化的结果:
int main()
{
int i = 0;
for(i=0; i<=999999; i++)
{
int count = 1;
int tmp = i;//这里使用中间变量tem是因为防止后面i的值被修改从而影响循环
int sum = 0;
while(tmp/10)
{
count++;
tmp = tmp/10;
}
tmp = i;
while(tmp)
{
sum += (int)pow(tmp%10, count);
tmp = tmp/10;
}
if(sum == i)
printf("%d ", i);
}
return 0;
}