Number Sequence /// oj21456

题目大意:

有一组规律数

the first 80 digits of the sequence are as follows:

1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 12345678910......

t组测试数据 

每次给定一个n 输出第n个数字是什么 (如:80 答案则为0而不是数10)

将整组数分成多段 即 1、12、123、1234、12345 .....

预处理出所有段的长度 f [ ] 并将所有长度处理成前缀和 s [ ]

输入n后 先找到其所在的整段

n减去之前的段长 就能得到在其所在段的位置ind

因为规律是在前一小段的基础上加上下一个数

所以可以再找到其位置之前的前驱段

(如: 所在整段为 12345 若ind为4 那么其前驱段为123

找到ind前驱段后 就能得到ind所在的数是多少

再按这个数的 位数 和 ind位置 判断数字

#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;

ll f[35000], s[35000];
void init()
{
    int c=0;
    s[c]=0LL; f[c++]=0LL;
    s[c]=1LL; f[c++]=1LL;
    for(double i=2;s[c-1]<=2147483647;i++)
        f[c]=f[c-1]+(ll)log10(i)+1LL,
        s[c]=s[c-1]+f[c], c++;//, printf("%d %lld
",c-1,s[c-1]);
}

int main()
{
    init();
    int t; scanf("%d",&t);
    while(t--) {
        ll n; scanf("%lld",&n);

        int k=1;
        while(s[k]<n) k++;
        int ind=n-s[k-1];

        k=1;
        while(f[k]<ind) k++;
        ind-=f[k-1];

        int ans;
        for(int i=(int)log10((double)k)+1;k;i--,k/=10)
            if(ind==i) { // 按位数和位置判断
                ans=k%10; break;
            }
        // ans=(int)pow((double)10,f[k]-ind)%10; 也可以直接用这个式子得到
        printf("%d
",ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zquzjx/p/9682191.html