什么是水仙花数?
“水仙花数”是指一个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; }
运行结果:
算法优化:
这里面求次方和其实可以用 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; }