Description
A single positive integer i is given. Write a program to find the digit located in the position i in the sequence of number groups S1S2…Sk. Each group Sk consists of a sequence of positive integer numbers ranging from 1 to k, written one after another.
For example, the first 80 digits of the sequence are as follows:
11212312341234512345612345671234567812345678912345678910123456789101112345678910
Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by one line for each test case. The line for a test case contains the single integer i (1 ≤ i ≤ 2147483647)
Output
There should be one output line per test case containing the digit located in the position i.
Sample Input
2
8
3
Sample Output
2
2
题解
题意:
1
12
123
1234
12345
123456
1234567
12345678
123456789
12345678910
1234567891011
123456789101112
12345678910111213
1234567891011121314
123456789101112131415
.........
- 在这样的序列中找出第i位数字(第6位是3)
思路:
- 可以将序列分成上面那样的若干行。找到第i行数字的位数与第i-1行的关系:len[ i ] = len[ i-1] + log10( i ) + 1。为了初步确定第i位数的位置,可以将前 k 行位数总和算出来:sum[ k ] = sum[k-1] + len[k]。
- 所以总体来说就是,先打表,再确定行,再确定是这一行的第几个数,最后得到是这个数的第几位。
函数定义
double pow (double x, double y) // = xy
double log10 (double x) // = lg(x)
Code
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#define ll long long
#define MAX 40000
using namespace std;
ll len[MAX], sum[MAX];
void init()
{
len[0] = 0;
sum[0] = 0;
for(int i = 1; i < MAX; ++i)
{
len[i] = len[i-1] + (int)log10((double)i) + 1;
sum[i] = sum[i-1] + len[i];
}
}
int main()
{
ll t, i, n, n1;
init();
cin>>t;
while(t--)
{
cin>>n;
i = 0;
while(sum[i] < n)
++i;
n1 = n - sum[i-1];
i = 0;
while(len[i] < n1)
++i;
cout<<i/(ll)(pow(10.0, (double)(len[i] - n1)))%10<<endl;
}
}