Preguntas divertidas de Hankson (guía avanzada para la competencia de algoritmos, números redondos)

1. Enlace de título:

Calculadora-T2094

2. La idea principal del tema:

Dado que (a0, x) = a1, [b0, x] = b1

Encuentre el número de soluciones que satisfacen la fórmula x anterior.

3. Análisis:

Como [b0, x] = b1, x es un divisor de b1

Y b1 tiene solo 10 factores primos como máximo, por lo que podemos considerar la composición de factores primos de x.

Actualmente se está considerando el factor primo p

Sea m [0] el número de p en a0, m [1] denota el número de p en a1,

     m [2] representa el número de p en b0, m [3] representa el número de p en b1 y ans representa el número de p en x.

Si m [0] <m [1], entonces ans no tiene solución; si m [0] == m [1], entonces ans> = m [1]; si m [0]> m [1], entonces ans == m [1].

Si m [2] <m [3], entonces ans == m [3]; si m [2] == m [3], entonces ans <= m [1]; si m [2]> m [3 ], entonces ans no tiene solución.

Así que simplemente escriba la tabla de números primos y enumere los números primos.

Nota: 1. Si b1% prima [i], debe continuar, porque b1 tiene sólo 10 factores primos diferentes como máximo, por lo que la mayoría de los casos se pueden eliminar.

           2. Después de enumerar todos los números primos, si b1> 1, es decir, b1 es un número primo, el número de esquemas para el factor b1 debe calcularse nuevamente.

4. Implementación del código:

#include <bits/stdc++.h>
using namespace std;

const int M = (int)45000;

int prime[M + 5], cnt;
bool is_prime[M + 5];

int a0, a1, b0, b1;

void get_prime()
{
    cnt = 0;
    memset(is_prime, 1, sizeof(is_prime));
    is_prime[0] = is_prime[1] = 0;
    for(int i = 1; i <= M; ++i)
    {
        if(is_prime[i]) prime[++cnt] = i;
        for(int j = 1; j <= cnt && i * prime[j] <= M; ++j)
        {
            is_prime[i * prime[j]] = 1;
            if(i % prime[j] == 0)   break;
        }
    }
}

void divide(int& m, int& n, int p)
{
    m = 0;
    while(n % p == 0)
    {
        m++;
        n /= p;
    }
}

int work(int p)
{
    int m[4], ans = 1;
    divide(m[0], a0, p);
    divide(m[1], a1, p);
    divide(m[2], b0, p);
    divide(m[3], b1, p);
    if(m[0] == m[1] && m[2] == m[3] && m[1] <= m[3])        return m[3] - m[0] + 1;
    else if(m[0] == m[1] && m[2] < m[3] && m[1] <= m[3])    return 1;
    else if(m[0] > m[1] && m[2] < m[3] && m[1] == m[3])     return 1;
    else if(m[0] > m[1] && m[2] == m[3] && m[1] <= m[3])    return 1;
    else                                                    return 0;
}

int main()
{
    get_prime();
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d %d %d %d", &a0, &a1, &b0, &b1);
        int ans = 1;
        for(int i = 1; i <= cnt && prime[i] <= b1; ++i)
        {
            if(b1 % prime[i])               continue;
            if(!(ans *= work(prime[i])))    break;
        }
        if(b1 > 1)  ans *= work(b1);
        printf("%d\n", ans);
    }
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/The___Flash/article/details/104212323
Recomendado
Clasificación