2. 菜鸟仓库是一个很大很神奇的地方,各种琳琅满目的商品整整齐齐地摆放在一排排货架上,通常一种品类(sku)的商品会放置在货架的某一个格子中,格子设有统一的编号,方便工人们拣选。 有一天沐哲去菜鸟仓库参观,无意中发现第1个货架格子编码为1,第2-3个分别为1,2,第4-6个格子分别是1,2,3,第7-10个格子编号分别是1,2,3,4,每个格子编号都是0-9中的一个整数,且相邻格子的编号连在一起有如下规律 1|12|123|1234|...|123456789101112131415|...|123456789101112131415……n 这个仓库存放的商品品类非常丰富,共有1千万多个货架格子。沐哲很好奇,他想快速知道第k个格子编号是多少?
问题的关键在于 123456789之后是1234567891还是12345678910;
Solution 1
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; string str = to_string(candinum); if (b == 0) x = str[step - 1] - '0'; else x = str[b - 1] - '0'; return x; }
(ps:作者:牛客3978382号;链接:https://www.nowcoder.com/discuss/34893?type=0&order=0&pos=9&page=2;来源:牛客网)
Solution 2
int Get1(int n) { if (n < 1) return -1; int x; string data = "1"; string temp = "1"; int count = 2; while (data.size() < n) { temp += to_string(count); count++; data += temp; } x = data[n - 1] - '0'; return x; }
(ps:作者:文不对题;链接:https://www.nowcoder.com/discuss/34893?type=0&order=0&pos=9&page=2;来源:牛客网)