Number Sequence
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 42304 | Accepted: 12331 |
Description
A single positive integer i is given. Write a program to find the digit located in the position i in the sequence of number groups S1S2...Sk. Each group Sk consists of a sequence of positive integer numbers ranging from 1 to k, written one after another.
For example, the first 80 digits of the sequence are as follows:
11212312341234512345612345671234567812345678912345678910123456789101112345678910
Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by one line for each test case. The line for a test case contains the single integer i (1 ≤ i ≤ 2147483647)
Output
There should be one output line per test case containing the digit located in the position i.
Sample Input
2
8
3
Sample Output
2
2
dp[i]存储到达i段时的总长,a[i]储存i段长度(emmm注释是另一种写法,清晰明了,还有第i位是几位这样子)
被安利了一个很棒的函数 log10() 可以非常方便地算出当前数字的位数 log10(i)+1
得到数i后,lower_bound函数二分到大于等于i的第一个数dp[pos],即数i在第pos段里;可以得到数i在pos段里是p=i-dp[pos-1]位;
得到p之后,lower_bound函数二分出大于等于p的第一个数a[q],即pos段p位是第q个数就是q中的一位;可以得到数i在pos段q数第m位m=p-a[q-1];
循环求出m位即可。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=40000;
int main()
{
int t;
long long i;
long long dp[maxn+10],/*s[maxn+10],*/a[maxn+10]; //dp当前j总长 s不同j分别多长 a当前位位数
int ans;
dp[0]=a[0]=0;
for(long j=1;j<=maxn;++j){
a[j]=a[j-1]+log10(j)+1; //log10真是太机智了
dp[j]=dp[j-1]+a[j];
}
scanf("%d",&t);
while(t--){
scanf("%lld",&i);
long pos=lower_bound(dp,dp+maxn,i)-dp;
long p=i-dp[pos-1];
long q=lower_bound(a,a+maxn,p)-a;
long m=p-a[q-1];
long x=log10(q)+2-m;
while(x){
--x;
ans=q%10;
q=q/10;
}
printf("%d\n",ans);
}
return 0;
}