poj1019 Number Sequence

Number Sequence
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 40638   Accepted: 11826

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
题目大意:给你一串由某个规律生成的数列,问第i位上的数字是几.
分析:非常简单的一道题.预处理两个数组,一个是1~i的数字位数,另一个统计前一个数组的前缀和,两次二分就搞定了.
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

const ll maxn = 34000;

ll a[100010], sum[100010], n, T,num[100010], cnt;

void init()
{
    a[1] = 1;
    sum[1] = 1;
    for (ll i = 2; i <= maxn; i++)
    {
        a[i] = a[i - 1] + (ll)log10((double)i) + 1;
        sum[i] = sum[i - 1] + a[i];
    }
}

ll solve(ll x)
{
    ll l = 1, r = maxn, ans = 0;
    while (l <= r)
    {
        ll mid = (l + r) >> 1;
        if (sum[mid] <= x)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
    x -= sum[ans];
    if (x == 0)
        return ans % 10;
    l = 1, r = maxn;
    while (l <= r)
    {
        ll mid = (l + r) >> 1;
        if (a[mid] <= x)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
    x -= a[ans];
    if (x == 0)
        return ans % 10;
    else
    {
        ans++;
        cnt = 0;
        while (ans)
        {
            num[++cnt] = ans % 10;
            ans /= 10;
        }
        for (ll i = cnt; i >= 1; i--)
        {
            x--;
            if (x == 0)
                return num[i];
        }
    }
}

int main()
{
    init();
    scanf("%lld", &T);
    while (T--)
    {
        scanf("%lld", &n);
        printf("%lld
", solve(n));
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zbtrs/p/7955229.html