第二题下来想了想,用模拟那个模式做的,简单测试下没啥问题,不知道有不有更高效的算法
#include<iostream>
#include<vector>
#include<climits>
#include<sstream>
using namespace std;
int Get(int n) {
int x;
int n1 = n;
int cnt = 9;
int step = 1;
int startn = 0 + step;
int endn = cnt*step + 0;
int numl = 0;
while (1) {
// 统计当前 step 的所有段总共覆盖 grid 编号数
// step 为 1:45个
// step 为 2:9000个
numl = (startn + endn) * cnt / 2;
if (n1 <= numl )
break;
n1 -= numl;
step <<=1;
cnt *= 10;
startn = endn + step;
endn = endn + step * cnt;
}
// 确定了step,确定在某一段的第几位
// step 为1:| 1 | 12 | 123 | 1234 |...
// step 为2:| 12345678910 | 1234567891011| ...
int m = startn;// 第一段的编号数
int prevm = 0;
int ii = 1;
while ( n1 > m ) {
prevm = m;
m += (startn+ii*step); // 逐段查看,累积前面的编号数
++ii;
}
n1 -= prevm;
// 从grid 编号段中(1234567891011...),要取出 第 n1 位的数(以1为索引开始)
step = 1;
cnt = 9;
int candinum = 0;
while (1) {
// 当前 step 所有数字的位数
// step为1: 9 (1~9)
// step为2: 180 (10~99)
numl = cnt * step;
if (n1 <= numl)
break;
n1 -= numl;
candinum += cnt;
step <<= 1;
cnt *= 10;
}
// 再次确定step,从编码段 以step位数递增的某个数 的第 n1 位数
// 如:|123.....100101102|
// 101就是以step=3递增的第2个数,
int a = n1 / step; // 第几个数
int b = n1 % step; // 第几位
candinum += a;
if (b > 0)
candinum += 1;
stringstream s;
string str;
s << candinum;
s >> str;
if(b==0)
x = str[step-1] - '0';
else
x = str[b-1] - '0';
return x;
}
int main()
{
int n;
while (cin >> n) {
int r = Get(n);
cout << '\t' << r << endl;
}
}