La maravillosa secuencia de Gugudong

Título: La maravillosa secuencia de
Gugudong Título:
Inserte la descripción de la imagen aquí
Entrada:
Inserte la descripción de la imagen aquí
Salida:
Inserte la descripción de la imagen aquí
Muestra:Inserte la descripción de la imagen aquí

Ideas para resolver problemas: este problema sigue siendo muy difícil, principalmente porque los datos son demasiado grandes, si usa el prefijo y solo puede pasar los primeros seis puntos, 1e18 no es una broma y el número no se puede reunir; aquí está mi idea: primero , Primero creo una matriz de tamaño 8, almacenando el número de 1-10 ^ I: por
ejemplo, el primer elemento de la matriz es
112123123412345 ... 123456789 el tamaño es 45 y el
segundo elemento de la matriz es
112123 ... 123 ... 9123 ... 10123 ... 11 ... 123 ... 99 a 99, el
tercer elemento a 999,
hasta el octavo elemento (porque el noveno elemento ya es mayor que 1e18, así que hasta el octavo elemento)
, resto k menos que k El elemento más grande; en
este momento, el resto de k es 123 ... (10 ^ I) 123 .... (10 ^ i + 1) ... el último elemento de cada grupo (es decir, 123 ... x, después de x es 1) Lo mismo; después de eso, k se usa para restar continuamente el número de elementos en cada grupo hasta que k sea menor que el número de elementos en ese grupo, pero debe tenerse en cuenta aquí que si k es demasiado grande, se agotará el tiempo; así que usé el método de dicotomía aquí Optimicé el tiempo de esta elección; el resto es un grupo de 123 ... x, y el k es uno de ellos Bien, aquí utilizo el método recursivo, primero comparo k y 9, y lo comparo con mayor que 9 y luego 180 (10, 11, ... 99 en total 180 bits), y luego continúo comparando. . . Hasta que sea menor o igual que, y luego el número de elementos restantes sea el mismo (el primer elemento debe ser 10 a la potencia de i), usted sabe k, solo pregunte;

Código:

#include<iostream>
#include<cmath>
using namespace std;
long long t[17]={0};
long long h[17]={0};
long long t1[17]={0};
void solve()
{
    h[0]=1;
    for(int i=1;i<=18;i++)
    {
        h[i]=h[i-1]*10;
    }
    t[0]=0;
    t1[0]=0;
    for(int i=1;i<=16;i++)//t1[i]存的是从1-10^i-1的元素的个数
    {
        t1[i]=t1[i-1]+i*(h[i]-h[i-1]);
    }
    for(int i=1;i<=8;i++)//t[i]存的就是从组1到组123...10^1-1的元素的个数
    {
        t[i]=t[i-1]+(h[i]-h[i-1])*t1[i-1]+i*(h[i]-h[i-1])*(h[i]-h[i-1]+1)/2;
    }
}
long long sol1(long long k,int num)
{
    long long t=(h[num]-h[num-1])*num;
    if(k<=t)//小于等于的情况,这时剩下的元素的位数相同,且第一个元素和k已经知道
    {
        long long k1=(k-1)/num;//这里就是求第k的数字
        long long k2=k%num;
        long long n=h[num-1]+k1;
        if(k2==0)
        {
            n=n%10;
            return n;
        }else
        {
            long long u=n;
            int total=0;
            while(u>0)
            {
                u=u/10;
                total++;
            }
            total=total-k2;
            for(int i=0;i<total;i++)
            {
                n=n/10;
            }
            n=n%10;
            return n;
        }
    }else//大于前去递归
    {
        k=k-t;
        return sol1(k,num+1);
    }
}
long long sol(long long k)
{
    long long p;
    for(int i=8;i>=0;i--)
    {
        if(t[i]<=k)
        {
            k=k-t[i];
            p=i;
            break;
        }
    }
    if(k==0){return 9;}//减去那个最大的,如果为0直接返回9就行
    long long p1=t1[p];//这个是减去的那个从1-10^i-1的元素的个数
    p++;
    while(1)
    {
        p1+=p;//这个是1-10^i的元素的个数
        long long l=0,r=1000000000;
        while(l+1<r)//二分
        {
            long long mid=(l+r)/2;
            long long tt=mid*p1+p*(mid-1)*mid/2;
            if(k>tt)
            {
                l=mid;
            }else
            {
                r=mid;
            }
        }
        k=k-(l*p1+p*(l-1)*l/2);//减去,之后剩下的就是123....x
        k=sol1(k,1);//判断
        return k;
    }
}
int main()
{
    solve();
    int q;
    cin>>q;
    while(q--)
    {
        long long k;
        cin>>k;
        long long h1=sol(k);
        cout<<h1<<endl;
    }
}
PGZ
Publicado 34 artículos originales · elogiado 0 · visitas 862

Supongo que te gusta

Origin blog.csdn.net/qq_43653717/article/details/105396217
Recomendado
Clasificación