poj1019

规律题

View Code
#include <iostream>

using namespace std;



long long        mi[20], len[50], eachlen[50];



long long    make(long long num, long long n)

{

    long long        i, x, goal;



    i = 1;

    while (true)

    {

        if (n > i * (mi[i] - mi[i - 1]))

            n -= i * (mi[i] - mi[i - 1]);

        else

            break;

        i++;

    }

    x = n / i;

    if (n % i == 0)

        x -= 1;

    n -= x * i;

    goal = x + mi[i - 1];

    n = i - n + 1;

    for (i = 0; i < n - 1; i++)

        goal /= 10;

    return goal % 10;

}



long long    work(long long n)

{

    long long        i, start, each, l, r, mid, num;

    

    i = 0;

    while (n > len[i])

        i++;

    i--;

    start = i;

    n -= len[i];

    each = eachlen[i];

    l = 0;

    r = mi[start + 1] - mi[start];

    while (l < r)

    {

        mid = (l + r) / 2;

        if ((l + r) % 2 != 0)

            mid +=1;

        if ((each + start + 1 + each + mid * (start + 1)) * mid / 2 < n)

            l = mid;

        else

            r = mid - 1;

    }

    mid = l;

    n -= (each + start + 1 + each + mid * (start + 1)) * mid / 2;

    num = mi[start] + mid;

    return make(num, n);

}



int main()

{

    long long        i, t, n;



    //freopen("t.txt", "r", stdin);

    mi[0] = 1;

    for (i = 1; i <= 5; i++)

        mi[i] = mi[i - 1] * 10;

    memset(len, 0, sizeof(len));

    memset(eachlen, 0, sizeof(eachlen));

    for (i = 1; i <= 5; i++)

    {

        len[i] = len[i - 1];

        len[i] += eachlen[i - 1] * (mi[i] - mi[i - 1]);

        len[i] += (i + i * (mi[i] - mi[i - 1])) * (mi[i] - mi[i - 1]) / 2;

        eachlen[i] += eachlen[i - 1];

        eachlen[i] += i * (mi[i] - mi[i - 1]);

    }

    cin >> t;

    while (t--)

    {

        cin >> n;

        cout << work(n) << endl;

    }

    return 0;

}

 

你可能感兴趣的:(poj)