百练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; }