有一串数字串,其规律为
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 123456789101112······k
输入位置n,计算这一串数字第n位是什么数字,注意是数字,不是数!例如12345678910的第10位是1,而不是10
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
long long sum[40005]; //数组sum是起点到i的数的总位数
int judge(int x) //判断数的位数
{//1到9的位数为1,10为2
int count = 1;
while(x / 10)
{
count++;
x /= 10;
}
return count;
}
int fun(int x) //10的x幂
{
int sum = 1;
for(int i = 1; i <= x; ++i)
sum *= 10;
return sum;
}
void solve() //打表
{
int sumn = 0;
memset(sum, 0, sizeof(sum));
for(int i = 1; i < 40005; ++i)
{
sumn += judge(i);//每次循环,SUMN表示第i组有多少位数字
sum[i] = sum[i - 1] + sumn;//sum[i]表示从起点到第i组最后一位数字有多少位
}
}
void answer(int x)
{
//用二分查找更快
int ans, i, j, summ;
i = 1;
while(sum[i] < x) //询问的位数在sum[i]中的位置
i++;
ans = x - sum[i - 1];//在第i组中,还需要ans位
summ = 0;
for(j = 1; j <= i; ++j) //询问位数在1到j的哪个具体的数字中
{
summ += judge(j);
if(summ >= ans)//在第I组的第j个数字中
break;
}
if(summ == ans) //相等,第J个数字的最后一位即为所求
printf("%d\n", j % 10);
if(summ > ans)
/* 不相等,比如还需要2位,而summ=5(比如对应的数为12345)
,那么2即为所求fun(summ - ans)=10^3(此为多余
的位数),j=12345,j / fun(summ - ans)=12345/1000=12*/
printf("%d\n", (j / fun(summ - ans)) % 10);
}
int main()
{
int ncase;
scanf("%d", &ncase);
solve();
while(ncase--)
{
int pos;
scanf("%d", &pos);
answer(pos);
}
return 0;
}