题意:
一串序列从1<i<n,分成n个序列依次排序,每个序列1到i排列。问第m个数是什么数。
思路:
先求出每个小序列分别用多少个数,然后确定m在什么位置,减去之前区间的所有位置,在在这个小序列里找就好了,找的时候貌似利用(int)log10(double(i))+1 这个公式会很简单,我做完才发现的QAQ。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
long long a[1005];
long long b[1005];
long long c[46345+10];
long long d[46345+10];
long long f(long long x)
{
int i, j;
for(i=1;i<=10; i++)
{
if(x<=b[i])break;
}
x-=b[i-1];
long long y=x/i;
if(x%i)y++;
y+=(long long)(pow(10.0, i-1))-1;
long long mod=x%i;
if(mod) for(j=1; j<=i-mod; j++)
{
y/=10;
}
return y%10;
}
int main()
{
int t;
int i;
long long x, y=0;
b[0]=a[0]=0;
for(i=1; i<=10; i++)
{
x=(long long) pow(10.0, i);
a[i]=i*(x-1-y);
b[i]=a[i]+b[i-1];
y=x-1;
// printf("%lld %lld\n", a[i], b[i]);
}
int k;
d[0]=0;
for(k=1; k<10; k++){c[k]=k;d[k]=d[k-1]+c[k];}
long long sum=0;
for(k=10; k<46345; k++)
{
int len=0, x=k;
while(x>0)
{
len++;
x/=10;
}
c[k]=c[k-1]+len;
d[k]=d[k-1]+c[k];
sum+=d[k];
}
// printf("%lld\n", sum);
scanf("%d", &t);
while(t--)
{
long long n;
scanf("%lld" ,&n);
for(i=1; i<46345; i++)
{
if(n<=d[i])
{
break;
}
}
n-=d[i-1];
printf("%lld\n", f(n));
}
return 0;
}