水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:$153=1^3+5^3+3^3$。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
输出样例:
153
370
371
407
#include <stdio.h>
#include <math.h>
int sumDaffodil(int,int*);
int main(int argc, const char *argv[])
{
int n,i,j,k;
scanf("%d",&n);
int start,end;
int arr[7] = {0};
if(n>=3 && n<=7)
{
start = pow(10,n-1);
end = pow(10,n);
for(i=start;i<end;i++)
{
k=i;
for(j=n-1;j>=0;j--)
{
arr[j] = k%10;
k /= 10;
}
if(i == sumDaffodil(n,arr))
printf("%d\n",i);
}
}
return 0;
}
int sumDaffodil(int n,int* arr)
{
int i,j,sum = 0,mul = 1;
for(i=0;i<n;i++)
{
mul = 1;
for(j=0;j<n;j++)
{
mul *= arr[i];
}
sum += mul;
//sum += pow(num%10,n);
//num /= 10;
}
return sum;
}
总结
本题的思路其实比较清晰:首先要有一个大循环来遍历n位正整数,在遍历过程中对每一个正整数进行拆分求各位数的n次幂和。求幂可以调用函数pow(),但如果对所以求幂都都要pow(),会发现当n过大时调用pow()的次数会非常大,结果是耗时长无法通过测试。
解决方法是:一是将循环的范围拎到for()之前单独计算start和end。二是改用数组先保存当前遍历的正整数的各位数,在sumDaffodil函数中改用for循环对数组中每一位进行n次自乘来取代pow()。
最后耗时342ms,测试时间限制是2500ms,可见pow()函数调用多了是多么耗时。(假设n=7,那么原先在
for(i=pow(10,n-1);i<pow(10,n);i++))
中要调用9000000次,在这个for循环中每次都要调用sumDaffodil函数,该函数中有一个for(i=0;i<n;i++)循环,每次循环要调用一次sum += pow(num%10,n);
,即函数中要调用7次,那么一共需要调用7*9000000=6300 0000次的pow()函数。)
本文链接:https://shengto.top/c/pat_26.html
转载时须注明出处及本声明