http://poj.org/problem?id=1019
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
题意:就是给你一个有规律的字符串,然后随便给你一个数N然后让你输出第N位是多少。
这是我们学校的一道月赛题,比赛时我没有找到什么规律,直接暴力求解,结果一直是RTE。。。杯具啊!看看别人的解题报告还是有点不太懂,但是我用别人思想结合我的代码,改了一下,竟然AC了,很是高兴。。
求数字位数的公式:log10((double)i) + 1
代码:
#include<iostream>
#include <math.h>
using namespace std;
#define N 32000
unsigned int a[32000],s[32000];
int getDigit(int n)
{
int i=1;
while(s[i]<n)
i++;
int pos=n-s[i-1];
if(pos==0) return (i-1)%10;
int sum=0;
for(int j=1;j<=i;j++)
{ int k=0;
int b[11];
int cc=j;
while(cc)
{ int bb=cc%10;
cc/=10;
b[k++]=bb;
}
for(int mm=k-1;mm>=0;mm--)
{
sum++;
if(sum==pos) return b[mm];
}
}
}
int main()
{
int i;
int t;
int n;
a[1]=1;
s[1]=1;
for(i=2;i<N;++i)
{
a[i]=a[i-1]+(int)log10((double)i)+1;
s[i]=s[i-1]+a[i];
}
cin>>t;
for(int j=0;j<t;++j)
{
cin>>n;
cout<<getDigit(n)<<endl;
}
return 0;
}
别人代码:
#include <iostream>
#include <cmath>
using namespace std;
unsigned int a[31270], s[31270];
/* 打表 */
void reset()
{
int i;
a[1] = 1;
s[1] = 1;
for(i = 2; i < 31270; i++)
{
/* 每一组数字都比上一组长 (int)log10((double)i) + 1 */
a[i] = a[i-1] + (int)log10((double)i) + 1;
s[i] = s[i-1] + a[i];
}
}
/* 计算 */
int work(int n)
{
int i = 1;
int length = 0;
/* 找到 n 所在的组 */
while (s[i] < n) i++;
/* n 在该组的下标 */
int pos = n - s[i-1];
/* length: n指向的数字的最后一位的下标 */
for (i = 1; length < pos; i++)
{
length += (int)log10((double)i) + 1;
}
/* 去掉所求位后面的数字然后取余 */
/* i: n指向的数字 + 1 */
return ((i-1) / (int)pow((double)10, length - pos)) % 10;
}
int main()
{
int t;
unsigned int n;
reset();
cin >> t;
while(t--)
{
cin >> n;
cout << work(n) << endl;
}
//system("pause");
return 0;
}