转载:
http://www.cnblogs.com/kuangbin/archive/2011/07/21/2113279.html
http://blog.csdn.net/lyy289065406/article/details/6648504
http://poj.org/problem?id=1019
题目:
Number Sequence
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 24168 |
|
Accepted: 6466 |
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
Source
Tehran 2002, First Iran Nationwide Internet Programming Contest
解题思路:
首先建议数学底子不好的同学,暂时放一放这题,太过技巧性了,连理解都很困难
模拟分组,把1看做第1组,12看做第2组,123看做第3组……那么第i组就是存放数字序列为 [1,i]的正整数,但第i组的长度不一定是i
已知输入查找第n个位的n的范围为(1 ≤ n ≤ 2147483647),那么至少要有31268个组才能使得数字序列达到有第2147483647位
注意:2147483647刚好是int的正整数最大极限值( ),所以对于n用int定义就足矣。但是s[31268]存在超过2147483647的位数,因此要用unsigned 或long 之类的去定义s[]
详细的解题思路请参照程序的注释。
其中数学难点有2:
(int)log10((double)i)+1
(i-1)/(int)pow((double)10,len-pos)%10
非常技巧性的处理手法,其意义已在程序中标明
另外要注意的就是log()和pow()函数的使用
两个都是重载函数,函数原型分别为
double log(double)
float log(float)
double pow(double , double)
float pow(float ,float)
所以当传参的类型不是double或float时,必须强制转换为其中一种类型,否则编译出错。一般建议用double
-
-
-
- #include
- #include
- using namespace std;
-
- const int size=31269;
-
- unsigned a[size];
- unsigned s[size];
-
-
-
-
-
- void play_table(void)
- {
- a[1]=s[1]=1;
- for(int i=2;i
- {
- a[i]=a[i-1]+(int)log10((double)i)+1;
- s[i]=s[i-1]+a[i];
- }
- return;
- }
-
-
-
- int compute(int n)
- {
- int i=1;
- while(s[i]
- i++;
-
- int pos=n-s[i-1];
-
- int len=0;
- for(i=1;len
- len+=(int)log10((double)i)+1;
-
- return (i-1)/(int)pow((double)10,len-pos)%10;
-
-
-
-
-
-
-
-
-
- }
-
- int main(void)
- {
- play_table();
-
- int test;
- cin>>test;
- while(test--)
- {
- int n;
- cin>>n;
- cout<
- }
- return 0;
- }