Number Sequence
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 32773 | Accepted: 9360 |
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
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
Source
Tehran 2002, First Iran Nationwide Internet Programming Contest
本题主要是数学的灵活应用,由题目可知,该数列是由n组数不断延伸得到的序列,第i组数的最后一个数为i,而题目要求得是某一位的数字,注意不是数,所以还要考虑对数的拆分,主要先是利用序列范围确定这n组数的n的范围,然后针对输入的每一个查找位先进行二分查找找到查找位所在组,然后利用指数和取余方法得到查找位的数位。
#include <cstdio>
#include <math.h>
#define N 31269
//因为序列的最长范围为2147483647 而dp[32168]可以超过这个长度要求
unsigned int dp[N];//记录到第i组数据为止的总长度
void init() //初始化记录长度
{
dp[1] = 1;
int temp = 1;
for(int i = 2; i < N; i++)
{
temp = temp + (int)log10(double(i)) + 1;
dp[i] = dp[i - 1] + temp;
}
}
int _search2(unsigned int x) //二分查找第i组dp数列
{
int left = 0, right = N - 1;
int middle;
while(left <= right)
{
middle = (left + right) / 2;
if(dp[middle] >= x )
right = middle - 1;
else
left = middle + 1;
}
return left;
}
int main()
{
int t, index;
unsigned int num, length, position;
int rs, i;
init();
scanf("%d", &t);
while(t)
{
scanf("%d", &num);
index = _search2(num);
position = num - dp[index - 1]; //在第index组数列里面的位置
length = 0;
for(i = 1; length < position; i++) //在第index组数列里面读取到position指向的数的最后一位的长度
length = length + (int)log10((double)i) + 1;
rs = (i - 1) / (int)pow(10, (double)(length - position)) % 10; //将position指向的数先去除position后面的部分,然后取余求得结果
printf("%d\n", rs);
t--;
}
return 0;
}