题意:给出一串那样的数字,很有规律的,总共有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, 0, sizeof(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;
}
#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, 0, sizeof(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;
}