编写函数,输入数字位数n,输出n位数字中所有的自幂数数。(所谓的自幂数是指一个n位数其各位数字的n次方等于该数本身,例如153是三位自幂数,因为:153=1+125+27。)
感谢小白程序进阶之路提供的的代码
#include
#include
#include
int isZiMiShu(int num, int n);
int main()
{
int n = 0, min = 1;
printf("请输入数字的位数:");
scanf("%d", &n);
//min = pow(10,(n-1));//注意,pow返回值应该是double类型,会出现一定误差,这里的结果不是10^5;
min = (int)(pow(10,(n-1))+0.5);//四舍五入
for (int i = min; i < min * 10; i++)//对每个数进行判断
{
if(isZiMiShu(i,n) == 1)//如果是自幂数
{
printf("%d\n",i);
}
}
}
int isZiMiShu(int num, int n)//num为具体的数,n为位数
{
if(n == 1)
{
return 1;
}
int StartNum = num;
int remainder;//余数
int sum = 0;
while(StartNum != 0)
{
remainder = StartNum % 10;//求余,54748,求余得8
StartNum /= 10;//54787,除10得5474
sum += (int)(pow(remainder, n)+0.5);
}
if( sum == num )
{
return 1;
}
else
{
return 0;
}
}
部分打表法适用于优化有限的量不大的值固定的复杂的重复的数据,例如该例中的0-9的n次幂。
其思路就是将复杂重复的计算值预先计算存储到数组中,需要用到时查询表格即可。
下面是实现1-5位自幂数的C语言代码:
#include
#include
#include
int pown[5][11]={{0,1,2,3,4,5,6,7,8,9,0},
{0,1,4,9,16,25,36,49,64,81,10},
{0,1,8,27,64,125,216,343,512,729,100},
{0,1,16,81,256,625,1896,2401,4096,6561,1000},
{0,1,32,243,1024,3125,11376,16807,32768,59049,10000}};
int isZiMiShu(int num, int n);
int main()
{
int n = 0, min = 1;
printf("请输入数字的位数:");
scanf("%d", &n);
//min = pow(10,(n-1));//注意,pow返回值应该是double类型,会出现一定误差,这里的结果不是10^5;
min = pown[n-1][10];
int i;
for (i = min; i < min * 10; i++)//对每个数进行判断
{
if(isZiMiShu(i,n) == 1)//如果是自幂数
{
printf("%d\n",i);
}
}
}
int isZiMiShu(int num, int n)//num为具体的数,n为位数
{
if(n == 1)
{
return 1;
}
int StartNum = num;
int remainder;//余数
int sum = 0;
while(StartNum != 0)
{
remainder = StartNum % 10;//求余,54748,求余得8
StartNum /= 10;//54787,除10得5474
sum += pown[n-1][remainder];
}
if( sum == num )
{
return 1;
}
else
{
return 0;
}
}
警告!此法慎用,老师看见头都给你打歪了
此法思路也很简单,与部分打表法优化部分复杂计算不同的是,全部打表法直接存储答案,需要哪组答案就输出哪组答案(O(1)复杂度,狗头保命)
下面是实现1-5位自幂数的C语言代码:
#include
#include
#include
int ans[5][11]={{0,1,2,3,4,5,6,7,8,9,-1},
{-1},
{153,370,371,407,-1},
{8208,9474,-1},
{48536,54748,92727,93084,-1}};
int main()
{
int n = 0;
printf("请输入数字的位数:");
scanf("%d", &n);
int i;
for (i = 0;; i++)
{
if(ans[n-1][i] == -1) break;//-1为结束标志
printf("%d\n",ans[n-1][i]);
}
return 0;
}