POJ-1019

-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <cmath>
using namespace std;

/**
* 思路: 先判断在第几组的第几位, 再判断是哪个数字, 再判断是这个数字的第几位
*/

int main() {
long long n;
cin >> n;

long long grp_len[99999], grp_idx[99999];
// grp_len[i] 表示第i个组的长度
// grp_idx[i] 表示第i个组的开始index
grp_len[0] = 0;
for (int i = 1; i < 99999; ++i) {
int len = log10(i) + 1; // log10(i) + 1 是 i 的长度, 别人代码上看到的, 比较有新意
grp_len[i] = grp_len[i - 1] + len;
}

grp_idx[0] = 0;
for (int i = 1; grp_idx[i - 1] <= (~0u >> 1); ++i) { // ~0u >> 1 表示最大int, 别人代码看到的
grp_idx[i] = grp_idx[i - 1] + grp_len[i];
}

while (cin >> n) {
/* cout << n << endl; */
int i, k;
for (i = 1; grp_idx[i] < n; ++i); // 比较得出第几个组, 可以用二分法优化
int j = n - grp_idx[i - 1]; // 第i组第j位(位数从1开始数)
for (k = 1; grp_len[k] < j; ++k); // 比较得出是第几个数字, 可以二分法优化
// 第k个数字的第倒数grp_len[k] - j + 1位(位数从1开始数)
int ans = k;
for (i = 0; i < grp_len[k] - j; ++i) {
ans /= 10;
}
ans %= 10;
cout << ans << endl;
}

return 0;
}
Author: comwrg
Link: https://comwrg.github.io/2019/03/25/POJ-1019/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.