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
此道题是Asia 2002, Tehran (Iran), Iran Domestic 一道竞赛题,ACM比赛的时候总时间是五个小时,题目好像一共有八道题,貌似我做这个题目的用时已经超过了五个小时^_^.坐下来的感觉确实还是相当的有点难度的,表面上看起来的题目貌似挺简单的,但真真实现起来的时候还真的不知如何下手!感兴趣的不妨试试!
我的思路是这样子的:先看数据的规律:
1
12
123
1234
12345
。。。
其实就是在上一个数的最后一个数(不是最后一位)加1得到下一个数,我的想法是定义一个数组nums[32000],用来保存每个数的长度!比如1的长度是1,12的长度是2,以此类推。。。.这样总的长度就是这些所有数的长度之和!所以要找第n位的数字,首先是先判断n落在数组nums[32000]哪个区间里(可以参看下面代码中的方法Find(int* nums, int n, int dig))!假如n是落在nums[10]里面,那么问题就转化成在nums[10]里面找第n-(nums[0]+nums[1]+...+nums[9])位是数字几了!其实也就是在类似于这样的数字12345678910111213...里面寻找了!这个时候问题就相对简单一点了!这个可以参考下面代码中的Find(int dig)方法,我就不多说了!
下面是我的C++代码,Run Time:0MS, Run Memory:184KB
using namespace std;
int a[4]={9,180,2700,36000};
int Power(int i, int j)
{
int total=1;
for(int k=1;k<=j;k++)
{
total*=i;
}
return total;
}
int Find(int dig)
{
int i;
for(i=0;i<4;i++)
{
if(dig<=a[i])break;
dig-=a[i];
}
int number=dig/(i+1);
int place=dig%(i+1);
if(place==0)
{
number+=Power(10,i)-1;
return number%10;
}
else
{
number+=Power(10,i);
int count=i+1-place+1;
while(count>1)
{
number/=10;
count--;
}
return number%10;
}
}
int Find(int* nums, int n, int dig)
{
int i=0;
for(i=0;i<n;i++)
{
if(dig<=nums[i])break;
dig-=nums[i];
}
return Find(dig);
}
int main(void)
{
int* nums = new int[32000];
nums[0] = 1;
double total = nums[0];
for (int i = 1; i < 32000; i++)
{
if (total >= 2147483647) break;
if(i<=9-1)
{
nums[i] = nums[i-1]+1;
}
else
{
if(i<=90+9-1)
{
nums[i] = nums[i-1]+2;
}
else
{
if(i<=90+9+900-1)
{
nums[i] = nums[i-1]+3;
}
else
{
if(i<=90+9+900+9000-1)
{
nums[i] = nums[i-1]+4;
}
else
{
nums[i] = nums[i-1]+5;
}
}
}
}
total += nums[i];
}
int t,dig;
cin>>t;
while(t>0)
{
cin>>dig;
cout<<Find(nums,32000,dig)<<endl;
t--;
}
return -1;
}