题目大意:
有一组规律数
the first 80 digits of the sequence are as follows:
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 12345678910......
t组测试数据
每次给定一个n 输出第n个数字是什么 (如:80 答案则为0而不是数10)
将整组数分成多段 即 1、12、123、1234、12345 .....
预处理出所有段的长度 f [ ] 并将所有长度处理成前缀和 s [ ]
输入n后 先找到其所在的整段
n减去之前的段长 就能得到在其所在段的位置ind
因为规律是在前一小段的基础上加上下一个数
所以可以再找到其位置之前的前驱段
(如: 所在整段为 12345 若ind为4 那么其前驱段为123
找到ind前驱段后 就能得到ind所在的数是多少
再按这个数的 位数 和 ind位置 判断数字
#include <cstdio> #include <cmath> #define ll long long using namespace std; ll f[35000], s[35000]; void init() { int c=0; s[c]=0LL; f[c++]=0LL; s[c]=1LL; f[c++]=1LL; for(double i=2;s[c-1]<=2147483647;i++) f[c]=f[c-1]+(ll)log10(i)+1LL, s[c]=s[c-1]+f[c], c++;//, printf("%d %lld ",c-1,s[c-1]); } int main() { init(); int t; scanf("%d",&t); while(t--) { ll n; scanf("%lld",&n); int k=1; while(s[k]<n) k++; int ind=n-s[k-1]; k=1; while(f[k]<ind) k++; ind-=f[k-1]; int ans; for(int i=(int)log10((double)k)+1;k;i--,k/=10) if(ind==i) { // 按位数和位置判断 ans=k%10; break; } // ans=(int)pow((double)10,f[k]-ind)%10; 也可以直接用这个式子得到 printf("%d ",ans); } return 0; }