第二题下来想了想,用模拟那个模式做的,简单测试下没啥问题,不知道有不有更高效的算法
#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;
	}
}