原题
原题链接
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 ;
}