题意:给出一串那样的数字,很有规律的,总共有2147483647位,然后问你第 n 位上的数字是多少。

 

思路:具体做法是用两个数组保存上面的数据。

1、[] 数组表示前面所有段的位数,a[i]表示前i段一共有多少位。

 

2、保存那一段具体的位数,b[]数组存储的是序列12345678910111213…各位位数对应数组的值,即b[1]=1, b[2]=2, b[3]=3, b[4]=4, b[5]=5, b[6]=6, b[7]=7, b[8]=8, b[9]=9, b[10]=1,b[11]=0, b[12]=1,b[13]=1, b[14]=1,b[15]=1, b[16]=1,b[17]=2, b[18]=1,b[19]=3

 

3、利用a数组计算出某段的第几位时,直接对应输出就可以b[i];

 

4、关键是求出是某一段多少位就可以啦。

 

CODE:

 

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;


long long a[32768], b[200010];
char str[10];

void init()
{
    long long  s = 0, k = 1;
    for(int i = 1; i < 32768; i++)
    {
        s = s + (int)(log10(double(i)))+1;       //求数字的位数 
        a[i] = a[i-1] + s;
    }
    for(int i = 1; i < 32768; i++)
    {
        memset(str, 0sizeof(str));
        sprintf(str, "%d", i);
        for(int j = 0; j < strlen(str); j++)
        {
            b[k++] = str[j]-'0';
        }
    }
}

int main()
{
    int T;
    scanf("%d", &T);
    init();
    while(T--)
    {
        long long q;
        scanf("%lld", &q);
        long long *p = lower_bound(a, a+32768, q);      //二分求下界,返回的是指针。 
        int ans = q-a[p-a-1];           //计算是某一子串的多少位
        printf("%lld\n", b[ans]);
    }
    return 0;
}

 

posted on 2012-10-15 17:26  有间博客  阅读(317)  评论(0编辑  收藏  举报