超级无敌简单题

原题

原题链接
Problem Description
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
鸽子数字由以下过程定义:从任何正整数开始,将数字替换为其各个数位的平方和,并重复该过程,直到该数字等于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

题意

给出“鸽子数”的定义,即为“快乐数” ,当一个数字的每一项的平方相加为1时,此数鸽子数;

思路

1.打表,数字为10位时,最大位9999999999,各项的平方和为810,所以只需将1~810中那些为鸽子数判断出来;之后仅需对所给数字进行判断即可,若数字判断一次后为鸽子数,那么此数字为鸽子数;

AC代码

#include<iostream>
using namespace std ; 

typedef long long ll ; 

int mark[1000] ; 

int text( int k )
{
	int cnt = 0 ; 
	
	while( k != 1 && cnt < 1000 ) 
	{
		int tmp = 0 ; 
		while( k != 0 ) 
		{
			tmp += ( k % 10 ) * ( k % 10 ) ; 
			k /= 10 ; 
		}
		k = tmp ; 
		cnt ++ ; 
	}
	return k == 1 ; 
}

int num[150005] ; 

int main()
{
	int n , ans , k = 0 , temp = 0 , p = 0 ;  
	
	for( int i = 0 ; i < 1000 ; i ++ )
	{
		if( text( i ) )
			mark[i] = 1 ; 
	}
	
	int a ; 
	
	for( int i = 1 , j = 0 ; i < 150000 ; j ++ ) 
	{
		a = j ; 
		int tmp = 0 ; 
		while( a != 0 ) 
		{
			tmp += ( a % 10 ) * ( a % 10 ) ; 
			a /= 10 ; 
		}
		if( mark[tmp] == 1 )
			num[i] = j , i ++ ; 
	}
	
	cin >> n ; 
	
	while( n -- ) 
	{
		cin >> k ; 
		cout << num[k] << endl ; 
	}
	return 0 ; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值