您的位置:首页 > 其它

POJ1019 ---简单的数学找规律题

2011-08-05 20:46 369 查看
Number Sequence

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 24387Accepted: 6534
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


题目大意就是给你这一串数字11212312341234512345612345671234567812345678912345678910123456789101112345678910……(未列完)

要我们求出第n个数是多少(从左到右看),例如第2个是1,第三个是2,第八个是2;

如果仔细观察这一串数字,可以发现他可以还分为很多小串,假设第i小串是123……i,假设第i小串所占的空间是a[i],则通过对比a[i]与a[i+1]发现,

第i+1串只比第i串多一个数,即i+1,故他们所占的空间差就是第i+1所占的空间。

对任意一个数所占的空间很好求,即 (int)log10(k)+1;

然后就可以求出每一个串的起始位置,通过与n比较就可以确定n出现在那一个串里,最后在求出n在这个串里的相对位置,就可以求出该题的解



参考代码

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int a1[32000] ;        //用来存储每一个串所占的空间
__int64 a[32000] ;    //用来存储每一个串的起始位置
int num[150000];    //打印出最大的一个串
int main()
{
int i;
a1[0]=0 ;
a1[1]=1;
for ( i = 2 ; i < 32000 ; i ++ )
a1[i] = a1[i-1] + (int)log10(1.0*i)+1;    //推导详见上文
a[0]=1;
for ( i = 1 ; i < 32000 ; i ++ )
a[i]=a[i-1]+a1[i-1];                    //上一个串的起点加所占空间就是下一个串的起点
int k = 1;
for ( i = 1 ; i < 31300 ; i ++ )
{//打印最大的一个串
char str[20];

str[0]='0';
int ti = i ;
int len = 0 ;
while (ti)
{
str[len]=ti%10+'0';
ti=ti/10;
len++;
}
while ( len -- )
{
num[k]=str[len]-'0';
k++;
}
}
int t;
cin >> t;
while ( t-- )
{
int mn;
cin >>mn;
for ( i =1; i < 32000 ; i ++ )
if ( a[i]>=mn )
break;
if ( a[i] ==mn )
cout<<1<<endl;
else
{//mn-a[i-1]+1就是其在第i-1个串里的相对位置
cout<<num[mn-a[i-1]+1]<<endl;
}
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: