Problem Description
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
通常来说,题面短的题目一般都比较难,所以我要把题面写得很长很长。
鸽子数字由以下过程定义:从任何正整数开始,将数字替换为其各个数位的平方和,并重复该过程,直到该数字等于1。如果不能,则这个数字不是鸽子数。
例如7是鸽子数,因为7->49->97->130->10->1。(7*7=49,4*4+9*9=97,9*9+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的数字,题目中叫鸽子数,实际上叫快乐数(happy number)有以下的特性:在给定的进位制下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必为1,现在让你求出第K个鸽子数。
题解:有两种解法:
1.因为假设一个数有十位,最大即9999999999,他的每一位平方和也才9*9*10即810,所以只需要先判断出1-810中有哪些数字为鸽子数,然后对后面的数进行第一次操作一定在810以内,直接判断是否为鸽子数即可,若第一次操作后为鸽子数,则这个大的数字一定也为鸽子数。
2.暴力打表,将前150000个鸽子数全部打出来,然后需要第几个输出第几个即可。
判断时可以用的规律,如出现{37,58,89,145,42,20,4,16}这几个数字,则一定不是鸽子数,相反也一定不是,比如73。或直接判断是否有4出现,有4出现一定不为鸽子数。
//第一种解法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int mark[1005];
int test(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(test(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++;
// printf("!!%d\n",j);
}
}
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d",&k);
printf("%d\n",num[k]);
}
}
大佬写的暴力:https://blog.csdn.net/weixin_43272781/article/details/88601829