首页 > 代码库 > math1019

math1019

有一串数字串,其规律为

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) //判断数的位数

{//19的位数为1102

int count = 1;

while(x / 10)

{

count++;

x /= 10;

}

return count;

}

 

int fun(int x) //10x

{

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) //询问位数在1j的哪个具体的数字中

{

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;

}

math1019