1003 超级无敌简单题[暴力打表]

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

我的题解:打表输出,发现非鸽子数在转化过程中会出现145,依次为判断依据,暴力打表.

#include <bits/stdc++.h>
const int N=15e5;
using namespace std;
int a[N];
char b[N];
bool check(int n){
    if(n==145) return false;
    if(b[n]==1) return true; else if(b[n]==0) return false;
    if(n==1) return true;
    int ans=0;
    int tn=n;
    while(n>0){
        int tmp=n%10;
        ans+=tmp*tmp;
        n/=10;
    }
    //cout<<ans<<endl;
    if(check(ans)){
            b[tn]=1;
            return true;
    }
    else{
        b[tn]=0;
        return false;
    }
}
int main()
{
    int t,n;
    int cnt=0;
    memset(b,-1,sizeof(b));
    for(int i=1;i<=14e5;i++){
        if(check(i)) a[++cnt]=i;
        if(cnt>=N-3) break;
    }
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        printf("%d
",a[n]);
    }

    //cout << "Hello world!" << endl;
    return 0;
}

官方题解:非鸽子数循环节长度为8,所以最多15次循环就可以判断是不是鸽子数,暴力打表

原文地址:https://www.cnblogs.com/-yjun/p/10544139.html