N位自幂数及打表法优化

题目描述

编写函数,输入数字位数n,输出n位数字中所有的自幂数数。(所谓的自幂数是指一个n位数其各位数字的n次方等于该数本身,例如153是三位自幂数,因为:153=1+125+27。)

代码实现

感谢小白程序进阶之路提供的的代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
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 <stdio.h>
#include <stdlib.h>
#include <math.h>
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 <stdio.h>
#include <stdlib.h>
#include <math.h>
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;
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒商

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值