快乐数及其升级版本(C语言)

题目描述 :
在这里插入图片描述
在这里首先了解一个小知识 , 当快乐数始终变不了1 , 陷入无限循环时 , 最终得到的结果就会是4 , 所以只需要判断结果是否等于4 , 如果为4 , 则就不是快乐数

代码如下 :

int Num(int x)
{
    int ret=0;
    while(x){
         ret+=(x%10)*(x%10);
        x/=10;
    }
    return ret;
}
bool isHappy(int n) {
    if(n<=0)
        return false;
    while(n!=1){
        n=Num(n);
        if(n==4)
            return false;
    }
    return true;
}

快乐数字由以下过程定义:从任何正整数开始,将数字替换为其各个数位的平方和,并重复该过程,直到该数字等于1。如果不能,则这个数字不是快乐数。
例如7是快乐数,因为7->49->97->130->10->1。(77=49,44+99=97,99+7*7=130…如此类推)
显然1是第一个快乐数。
有Q个询问,每个询问给出一个数k,你需要输出第k个快乐数。

Input

第一行一个Q,代表询问的个数(Q<=100000)
接下来Q行,每行一个数字k(k<150000)

Output

每行输出一个数,代表第k个数

Sample Input
2 1 2

Sample Output

1 7

ps:开始死循环没找不是快乐数在哪里断开。后来发现许多不是快乐数最后都会到4.

2->4->16->37->58->89->145->42->20->4

5->25->29->85->89->…->4

6->36->45->41->17->50->25->…->4


#include<iostream>
using namespace std;
 
const int maxn = 1000000;
const int maxm = 150000;
bool vis[maxn]={0};
int num[maxm+10];
 
int g(int n){
	if (n!=1 && n!=7 && n<10)//易知10以内的数就1和7,该条件为递归结束出口
		return 0;
	int sum = 0;
	while (n){
		int t = n % 10;
		n /= 10;
		sum += t * t;
	}
	if (vis[sum]) return 1;
	else return g(sum);
}
 
void init (){
	vis[1] = 1;
	num[1] = 1;
	for (int i=2,j=2;j<=maxm;i++){
		if (g(i)){
			vis[i] = 1;
			num[j++] = i;
		}
	}
}
 
int main(){
	init();
	int t;
	scanf("%d",&t);
	while (t--){
		int n;
		scanf("%d",&n);
		printf("%d\n",num[n]);
	}
	//for (int i=1;i<=20;i++)
	//	printf("%d ",num[i]);
	return 0;
}

以上是个打表的过程,通过记忆化搜索已经用空间换取了大部分时间,还可以结合许多非快乐数不等于4这个条件来改善代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值