题意:给定一个序列,问序列第i位数字;
思路:显而易见,在1~9中,序列长度依次增加1,在10~99中,序列长度依次增加2。那么我们可以求出所有num[n](num[n]以数n结尾的序列长度),因为给的条件(1 ≤ i ≤ 2147483647),所以n最大为31269(对所有的num[n]求个和就知道了);具体思路看代码吧;
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<vector>
#include<cstdio>
#define MAXN 33000
#define INF 0x3f3f3f3f
#define lmid l,m,rt<<1
#define rmid m+1,r,rt<<1|1
#define ls rt<<1
#define rs rt<<1|1
#define Mod 1000000007
#define i64 __int64
#define LIMIT_ULL 100000000000000000
#define Max(a,b) (a>b)?a:b
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
int s[31269];
char ch[10];
void init()
{
s[0]=0;
for(int i=1;i<=31268;i++)
{
int j=i;
int t=0;
while(j)
{
j/=10;
t++;
}
s[i]=s[i-1]+t;
}
}
int main()
{
init();
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int m;
for(int i=1;i<=31268;i++)//知道n所在的序列,该序列以m结尾
{
if(n<s[i])
{
m=i;
break;
}
n-=s[i];
}
if(n==0)//n==0说明n为前一个序列的末尾,即(m-1)%10
{
cout<<(m-1)%10<<endl;
continue;
}
for(int i=m-1;i>=1;i--)//找到第一个长度小于n的序列,该序列以m结尾
{
if(s[i]<=n)
{
m=i;
n-=s[i];
break;
}
}
if(n==0)//n==0说明n为该序列的末尾,即m%10
{
cout<<m%10<<endl;
continue;
}
for(int i=m+1;;i++)//枚举,确定n所在位置
{
int j=i;
int t=0;
while(j)
{
j/=10;
t++;
}
if(n>=t)
{
n-=t;
if(n==0)
{
cout<<i%10<<endl;
break;
}
continue;
}
if(n<t)
{
sprintf(ch,"%d",i);
cout<<ch[n-1]<<endl;
break;
}
}
}
return 0;
}