有趣的序列
题目描述
现在生成一个包含所有自然数的序列
123456789101112131415...
其中 d12 是数字 1
输入
输入三个数字 x,y,z(1≤x,y,z≤1,000,000)
输出
输出一个整数,代表dx×dy×dz
的结果
思路:
因为x,y,z范围是1e6,因此我们可以先预处理出sum[i]
代表i位数共占多少位置,并预处理出start[i]
代表i位数的起始数组
这样,我们传入位置后,若位置>sum[i]
,就用位置-=sum[i]
并查找下一位,若等于sum[i]
,就返回9(因为每位数的最后一个数字的最后一位都是9),若小于sum[i]
,就判断是第该位的哪一个数字的哪一位,并把该数返回即可
代码:
/*************************************************************************
> File Name: p.cpp
> Author: Zcy
> Mail: 296763002@qq.com
> Created Time: 三 1/23 18:16:17 2019
************************************************************************/
#include <stdio.h>
int sum[7] = {0, 9, 180, 2700, 36000, 450000, 5400000};
int start[7] = {0, 1, 10, 100, 1000, 10000, 100000};
int quick(int a, int b) {
int ans = 1;
while(b) {
if(b & 1) {
ans *= a;
}
b >>= 1;
a *= a;
}
return ans;
}
int getinx(int inx) {
for (int i = 1; i <= 6; i++) {
if (inx > sum[i]) {
inx -= sum[i];
} else if (inx == sum[i]) {
return 9;
} else {
int cs = inx / i;
int ys = inx % i;
if (ys == 0) {
cs = cs + start[i] - 1;
cs %= 10;
return cs;
} else {
cs = cs + start[i];
int ttt = quick(10, i - ys);
int kkk = cs / ttt;
kkk %= 10;
return kkk;
}
}
}
return -1;
}
int main () {
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
// for (int i = 1; i <= 1000; i++) {
// printf("%d", getinx(i));
// }
int xx = getinx(x);
int yy = getinx(y);
int zz = getinx(z);
printf("%d\n", xx * yy * zz);
return 0;
}
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢