题目来源:http://poj.org/problem?id=1019
题目大意:
给定一个正整数i,写一个程序,求序列S1S2...Sk中的第i位(digit)。其中Sk为正整数序列1到k连接起来。例如,前80个数位的序列如下:11212312341234512345612345671234567812345678912345678910123456789101112345678910。
输入:第一行表示有多少个测试用例。接下来的每行为一个正整数,即给出的i(1 ≤ i ≤ 2147483647).
输出:每行对应一个输入,为求得的第i位数字
Sample Input
2 8 3
Sample Output
2 2
最开始理解错了题意,把数位(digit)理解成了数字(num),后来明白了才重写。
由于1 ≤ i ≤ 2147483647,可知k最大不会超过31270。依次求出每个k所占用的哪些位,用len表示每个k占用的位数,end表示每个k最后一位所在的位置。然后先找到给定的i在哪个k的范围内,然后确定i处的数字是多少。
1 ////////////////////////////////////////////////////////////////////////// 2 // POJ1019 Number Sequence 3 // Memory: 556K Time: 0MS 4 // Language: C++ Result: Accepted 5 ////////////////////////////////////////////////////////////////////////// 6 7 #include <iostream> 8 #include <cmath> 9 10 using namespace std; 11 12 unsigned int len[31270]; 13 unsigned int end[31270]; 14 15 int main() { 16 int n; 17 cin >> n; 18 len[1] = 1; 19 end[1] = 1; 20 for (int i = 2; i < 31270; ++i) { 21 len[i] = len[i - 1] + (int) log10(double(i)) + 1; 22 end[i] = end[i - 1] + len[i]; 23 } 24 for (int p = 0; p < n; ++p){ 25 unsigned int k; 26 cin >> k; 27 int N = 1; 28 while (end[N] < k) { 29 ++N; 30 } 31 int pos = k - end[N - 1]; 32 int length = 0; 33 int i = 1; 34 while (length < pos) { 35 int digs = (int)log10(double(i)) + 1; 36 length += digs; 37 ++i; 38 } 39 cout << (i - 1) / ((int)pow(10, double(length - pos))) % 10<< endl; 40 41 } 42 system("pause"); 43 return 0; 44 }