PAT 1010 Radix (25 puntos)

Enlace del tema: haga clic aquí

Significado de la pregunta: ahora dados dos números enteros positivos N 1, N 2 N_1, \ N_2norte1, norte2, Y dé la base de uno de los números, encuentre la base del otro número, que puede hacer que los dos números sean iguales.

Consejo: si la etiqueta es igual a 2, intercambie los dos números, lo que puede reducir el código simétrico a la mitad.

Después del intercambio, N 1 N_1norte1Es una base conocida, N 2 N_2norte2Es de base desconocida. Pero el título no especifica el rango de datos de la base de entrada, por lo que N 1 N_1norte1También puede ser muy largo. Para que el problema se desarrolle sin problemas, el valor predeterminado es N 1 N_1norte1最大 为(zzzzzzzzzz) 36 (zzzzzzzzzz) _ {36}( z z z z z z z z z z )3 6, Que es N 1 N_1norte1El número decimal máximo de es 3 6 10 36 ^ {10}3 61 0 , siempre que se pueda usar.

Para base desconocida N 2 N_2norte2, Su base puede ser muy grande, la base más grande no es solo 36 363 6 es tan simple.

Si la fuerza bruta enumera N 2 N_2norte2 , Se agotará el tiempo.

Sabemos que cuanto mayor es la base, N 2 N_2norte2Cuanto mayor sea el número decimal representado, utilizando esta monotonicidad, podemos enumerar N 2 N_2 en dosnorte2Base. Borde izquierdo dicotómico lll es igual aN 2 N_2norte2El valor máximo de todos los caracteres en más 1 11 , el límite derecho de la dicotomía es igual aN 1 N_1norte1 Y 36 es el máximo de los dos.

Código AC:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long ll;

char a[15], b[15];
int tag, radix;

int get(char x)
{
    
    
    if(x >= '0' && x <= '9')  return x - '0';
    else    return x - 'a' + 10;
}

ll calc(ll r)
{
    
    
    ll res = 0;
    for(int i = 0; b[i]; i++)
    {
    
    
        if((double)res * r + get(b[i]) > 1e16) return 1e16;
        res = res * r + get(b[i]);
    }
    return res;
}

int main()
{
    
    
    scanf("%s%s%d%d", a, b, &tag, &radix);
    
    if(tag == 2)    swap(a, b); // 交换,以减少对称的代码量
    
    ll n1 = 0;
    for(int i = 0; a[i]; i++)   n1 = n1 * radix + get(a[i]);
    
    int maxb = -1;
    for(int i = 0; b[i]; i++)   maxb = max(maxb, get(b[i]));
    
    ll l = maxb + 1, r = max(n1, 36ll);
    
    while(l < r)                // 找到第一个大于等于n1所对应的进制
    {
    
    
        ll mid = l + r >> 1;
        if(calc(mid) >= n1) r = mid;
        else l = mid + 1;
    }

    if(calc(r) != n1)   puts("Impossible");
    else    printf("%lld\n", r);
    
    return 0;
}

La cuenta pública de WeChat "Búsqueda de empleo de competencia de algoritmos" está dedicada a explicar en detalle los principios y plantillas de algoritmos involucrados en la competencia y la búsqueda de empleo. ¡Bienvenido a prestar atención, comunicarnos y progresar juntos!

Supongo que te gusta

Origin blog.csdn.net/qq_42815188/article/details/109000006
Recomendado
Clasificación