O - Number Sequence(POJ 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
题解

题意:

1
12
123
1234
12345
123456
1234567
12345678
123456789
12345678910
1234567891011
123456789101112
12345678910111213
1234567891011121314
123456789101112131415
.........
  • 在这样的序列中找出第i位数字(第6位是3)

思路:

  • 可以将序列分成上面那样的若干行。找到第i行数字的位数与第i-1行的关系:len[ i ] = len[ i-1] + log10( i ) + 1。为了初步确定第i位数的位置,可以将前 k 行位数总和算出来:sum[ k ] = sum[k-1] + len[k]。
  • 所以总体来说就是,先打表,再确定行,再确定是这一行的第几个数,最后得到是这个数的第几位。

函数定义
double pow (double x, double y) // = xy
double log10 (double x) // = lg(x)

Code
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#define ll long long
#define MAX 40000
using namespace std;

ll len[MAX], sum[MAX];

void init()
{
    len[0] = 0;
    sum[0] = 0;
    for(int i = 1; i < MAX; ++i)
    {
        len[i] = len[i-1] + (int)log10((double)i) + 1;
        sum[i] = sum[i-1] + len[i];
    }
}

int main()
{
    ll t, i, n, n1;
    init();
    cin>>t;
    while(t--)
    {
        cin>>n;
        i = 0;
        while(sum[i] < n)
            ++i;
        n1 = n - sum[i-1];
        i = 0;
        while(len[i] < n1)
            ++i;
        cout<<i/(ll)(pow(10.0, (double)(len[i] - n1)))%10<<endl;
    }
   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值