百练1019 Number Sequence题目出处:http://poj.grids.cn/practice/1019
题目描述:
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
就不翻译了。大致意思是说St=1234...t(如S11=1234567891011)。然后S1S2S3...Sk串成一个长的字符串,然后在这个大的字符串中找出第i个字符。
代码即思路。留意注释即可。
#include<stdio.h>
#include <math.h>
#define Length 99999 //由于读入的测试样例并不太大,因此该数值是合理的
int getlength(int num)
{
return log10(num) + 1;
}
int getDigitInNum( int n, int num ) //求j的n位数字。如j:23578, n:2,则返回3
{
int t = getlength(num) - n;
while (t--)
num /= 10;
return num % 10;
}
int getDigitInS( int* s, int n )
{
int k = 1;
while (s[k] < n)
k++;
if (n == s[k])
return k % 10;
else
{
n = n - s[k-1];
return getDigitInNum(n, k); //要求的数字肯定的在j当中
}
}
int getDigit( int* cas, int* s, int n )
{
int k = 1;
while (cas[k] < n)
k++;
if (n == cas[k])
return k % 10;
else //说明第n位在Sk当中
{
n = n - cas[k-1]; //通过对n重新复制,转为求Sk中第n位数
return getDigitInS(s, n);
}
}
int main()
{
int s[Length] = {0};
int cas[Length] = {0};
int i;
//s[i]的值是串Si的长度,经检测无溢出
for (i = 1; i < Length; ++i)
{
s[i] = s[i-1] + getlength(i);
}
//cas[i]的值是串S1S2S3...Si的长度
for (i = 1; i < Length; ++i)
{
cas[i] = cas[i - 1] + s[i]; //cas[i]的值可能会有溢出
if (cas[i] < 0) //溢出时i的值为31268
break;
}
i--; //溢出前的i,后面还会用到
int testN; //测试样例个数
scanf("%d", &testN);
while (testN--)
{
int n, digit;
scanf("%d", &n); //读入测试样例的值
if (n > cas[i]) //溢出检测,用到之前的i值
digit = getDigitInS(s, n - cas[i]);
else
digit = getDigit(cas, s, n);
printf("%d\n", digit);
}
return 0;
}