Los problemas matemáticos algoritmo: máximo común divisor y el mínimo común múltiplo, fracción cuatro operaciones, números primos (primer rápido Computacional), factor de descomposición de primer

algoritmos matemáticos de problemas comunes

En el mundo de la informática, por lo general todavía tenemos que resolver algunos problemas de matemáticas, aquí hay algunos algoritmos matemáticos comunes para resumir el problema, con la esperanza de reducir la tasa de olvido.

El máximo común divisor y el mínimo común múltiplo

Máximo común divisor

números enteros positivos A y B es el máximo común divisor de la Convención se refiere al número máximo de todo común divisor de a y b en el uso general gcd(a, b)para representar el máximo común divisor de a y b, y el máximo común divisor utilizado para resolver el algoritmo de Euclides (platija división de fase).

algoritmo de Euclides basado en el siguiente teorema:

Establecer a, b son enteros positivos, gcd (a, b) = gcd (a, a% b)

Prueba: establecer a = kb + r, donde r k y b están divididos por un cociente y un resto obtuvieron

Hay r = a - kb establecieron

Sea d es un divisor común de ayb,

Entonces el r = a - un divisor kb, r, tienen también d

Por lo tanto d es un divisor común de b y r

Y r = a% b, d tienen un divisor común de b y a% b

Así, tanto el divisor d y b, a, b, y también el divisor de un% b

Debido a la naturaleza arbitraria de d, A y B tienen un divisor común es divisor de b y a% b

A = kb divisor de r, b, y misma razón a% b + a es divisor de b y

Así, un divisor y el divisor b, a% de B y B es igual a todo, por lo que el máximo común denominador son iguales

即 gcd (a, b) = mcd (b, a% b)

Si a <b, el resultado es el intercambio de a y b, y si a> b, entonces los datos pueden ser rápidamente más pequeño por el tamaño de este teorema. Así recursividad límite que? Como todos sabemos, cualquiera de los enteros 0 y un máximo común divisor es un, esta conclusión puede ser utilizado como una frontera recursiva. Como resultado, los dos se recursivo clave:

  1. La recursión: GCD (A, B) = GCD (B, A% B)
  2. límite recursiva: GCD (A, 0) = A

A continuación, puede ser obtenido siguiente código:

int gcd(int a, int b) {
  if(b == 0) return a;
  else return gcd(b, a % b);
}

El mínimo común múltiplo

Uso general lcm (a, b) para representar el mínimo común múltiplo de a y b.

El mínimo común múltiplo del máximo común divisor de resolución se basa en. Cuando el máximo común divisor de a y b dar d, se puede obtener inmediatamente el mínimo común múltiplo es ab y / D , ** ab ** puede desbordarse debido a que en la operación real, es más apropiado redacción es un / DB .

es decir, el máximo común divisor de a y b, un conjunto de la intersección de conjuntos b, y el mínimo común múltiplo de A y B, y se pone, como parte de un factor común de múltiples ab será calculado una vez, hay que deshacerse de un factor común

Puntajes cuatro operaciones

Puntuación cuatro medias aritméticas dado el numerador y el denominador de dos fracciones, el resultado aritmético requerido de la misma, a continuación se describen cómo representar y para simplificar una fracción.

la representación fraccionaria y simplificación

la representación fraccionaria

Para una puntuación, la forma más sencilla de la escritura se escribe fracciones impropias, es decir, si las moléculas del denominador más grandes o más pequeñas, conservan su número original, que puede ser utilizado para mantener la estructura:

struct Fraction{
    int up, down;
};

Tres reglas:

  1. El abajo no negativo, si el resultado es negativo, entonces formarán moléculas puede ser negativo
  2. Si la puntuación es exactamente igual a cero, la molécula que está predeterminado A 0, el denominador es 1
  3. Numerador y el denominador común divisor sin excepción 1

Simplificar fracciones

La simplificación se utiliza principalmente para hacer fracciones variables de reúnen tres requisitos expresados como una fracción, reduciendo así los pasos se dividen en los siguientes tres pasos:

  1. Abajo si el denominador es negativo, por lo que el numerador y el denominador se han convertido en su homólogo
  2. Si la molécula hasta 0, luego dejar que el denominador de 1
  3. Acerca de punto: la obtención de un valor absoluto de la denominador y los valores absolutos de molecular mayor divisor d común, de modo que la molécula se divide entonces por el denominador d

Código es el siguiente:

Fraction reduction(Fraction result) {
    if(result.down < 0) {   // 分母为负数,令分子分母都变味相反数
        result.up = -result.up;
        result.down = -result.down;
    }
    if(result.up == 0) {    // 如果分子为 0,令分母为 1
        result.down = 1;
    }else { 
        int d = gcd(abs(result.up), abs(result.down));  // 分子分母的最大公约数
        result.up /= d; 
        result.down /= d;   // 约去最大公约数
    }
    return result;
}

Puntajes cuatro operaciones

Las puntuaciones deben ser sobre los puntos de suma y resta, por lo que necesitan de la separación de la fórmula y se pueden calcular para la fórmula.

// 加法
Fraction add(Fraction f1, Fraction f2) {
    Fraction result;
    result.up = f1.up * f2.down + f2.up * f1.down;
    result.down = f1.down * f2.down;
    return reduction(result);
}

// 减法
Fraction minu(Fraction f1, Fraction f2) {
    Fraction result;
    result.up = f1.up * f2.down - f2.up * f1.down;
    result.down = f1.down * f2.down;
    return reduction(result);
}

// 乘法
Fraction mul(Fraction f1, Fraction f2) {
    Fraction result;
    result.up = f1.up * f2.up;
    result.down = f2.down * f2.down;
    return reduction(result);
}

// 除法
Fraction divide(Fraction f1, Fraction f2) {
    Fraction result;
    result.up = f1.up * f2.down;
    result.down = f1.down * f2.up;
    return reduction(result);
}

fracción de salida

requisitos de puntuación de salida deben ser objeto, tiene sustancialmente la siguiente nota:

  1. Antes de puntuación de salida, la necesidad de una simplificación de su primera
  2. Si la puntuación abajo denominador r es 1, lo que indica que el marcador es un número entero, por lo general molécula directamente salida
  3. Si la fracción r de moléculas hasta el valor absoluto es mayor que el denominador hacia abajo, lo que indica que la puntuación es fracciones impropias, esta vez debe ser de salida fracción mixta forma, es decir, la parte entera de r.up / r.down , resto molecular es abs (r.up) % menos
  4. Cuando la fracción descrito anteriormente no satisfacen la fracción adecuada para R, se emite como

El siguiente es un caso de salida:

void showResult(Fraction r) {
    r = reduction(r);
    if(r.down == 1) printf("%lld", r.up);
    else if(abs(r.up) > r.down) {
        printf("%d %d/%d", r.up / r.down, abs(r.up) % r.down, r.down);
    }else {
        printf("%d %d", r.up, r.down);
    }
}

Los números primos

También conocido como número primo prime, el número se refiere a una clase de su propio además de 1 y no puede ser dividido por otro número entero. Es decir, para un número entero positivo n dado, si por cualquier número entero positivo de un (1 <a <n) , son n % a != 0entonces conocido número primo n, el número de enganchado de otra manera. Especial atención no es ni un número primo, ni compuesto.

El primer juicio

N la determinación de si un número es primo, es necesario determinar si n es 2,3, ......, n-1 es divisible, no puede ser divisible sólo cuando, con el fin de determinar un número primo. Sin embargo, hemos encontrado que, si hay un mayor número digital del que aproximadamente sqrt (n), entonces debe ser un número que es aproximadamente sqrt (n) es menor que, hemos determinado sólo de 2 a sqrt (n).

Código es el siguiente:

bool isPrime(int n) {
  if(n <= 1) return false;
  int sqr = (int)sqrt(n);	// 根号 n
  for(int i = 2; i <= sqr; i++) {
    if(n % i == 0) return false;
  }
  return true;	// n 是素数
}

Si n no está cerca de la variable int límite superior de la gama, hay una redacción más sencilla:

bool isPrime(int n) {
  if(n <= 1) return false;
  for(int i = 2; i * i <= n; i++) {
    if(n % i == 0) return false;
  }
  return true;
}

preguntas escritas que llevaron cuando el límite superior de la gama de cerca de la variable int i * desbordamiento i (por supuesto 10 9 o menos será segura), la solución se define como la de tipo i largo tiempo, no lo harán desbordamiento.

Obtener primera mesa

Si tenemos que mirar a una amplia gama de todos los números primos, no hay ningún punto rápida manera de hacer eso?

"Screening" es una especie de una gran cantidad de métodos de detección sistemática es muy fácil de entender, la idea central es:

Algoritmos de pequeño a grande para enumerar todos los números para cada número primo, para eliminar a todos sus múltiplos, y el resto son números primos, y en el proceso, la única cosa que necesitamos dada la condición de arranque es que 2 es un número primo, después de se puede obtener por un ciclo de proceso.

Pequeño para llegar a un gran número de una, si no la pantalla a un paso anterior, entonces debe ser un número primo, porque si A no es un número primo, tiene que haber un factor primordial menos de una, debe ser descartado

Podemos utilizar para simular una pantalla de matriz de bool, si un [i] es verdadera, entonces el número primo es, si un [i] es, entonces, el número falsa no primo.

bool isPrime[maxn];
vector<int> prime;

void getPrime() {
  for(int i = 0; i < maxn; i++) {
    isPrime[i] = true;	// 开始认为所有的都是素数
  }
  isPrime[0] = isPrime[1] = false;
  for(int i = 2; i < maxn; i++) {
    if(!isPrime[i]) {
      continue;	// 如果是非质数则跳过
    }
    prime.push_back(i);
    for(int j = i * i; j < maxn; j+=i) {
      isPrime[j] = false;
    }
  }
  return;
}

factor de calidad de la descomposición

El llamado descomposición factor de calidad se refiere a un número entero positivo n se escribe como un producto de las formas principales o más.

Pero al final tiene que ser escrito como el producto de una serie de números primos distintos, por lo que bien podría salir primero primera mesa. Dado que cada factor de calidad puede aparecer más de una vez, por lo que bien podría estructura definida para mantener el factor de calidad y el número es:

struct factor{
  int x, cnt;
}fac[10];

Para un número entero positivo n, si es que existe dentro de los factores primos [2, n] gama, estos factores están por debajo o sqrt (n), a continuación, a lo sumo uno mayor que sqrt (n), de modo que aparezca idea:

  1. 1 Para enumerar todos los factores primos en el rango de sqrt (n), la determinación de si p es un factor de n
    1. Si p es un factor de n, a continuación, aumentar a una matriz fac factores primos p, e inicializa el número del mismo es 0, y si p es un factor de n, sea n p y constantemente dividiendo, para cada operación por lo que el número p plus 1, p no es hasta que el factor n
    2. Si n no es un factor p, entonces saltar
  2. Si n es todavía mayor que el final de la etapa 1 anterior, se describe un mayor n que sqrt (n) un factor, se añadió este factor en esta matriz fac tiempo.

Código es el siguiente:

PAT A1059

/*
    Author: Veeupup
 */
#include <cstdio>
#include <climits>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

const long maxn = 1e7;

vector<long> primes;     //  保存质数
bool isPrime[maxn];     //  质数判断

// 质数表初始化
void Initial() {
    fill(isPrime, isPrime + maxn, true);    // 所有的数字都初始化为 true,为质数,随后筛
    isPrime[0] = isPrime[1] = false;
    for(long i = 2; i < maxn; i++) {
        if(!isPrime[i]) 
            continue;   // 如果 i 不是质数,则跳过
        primes.push_back(i);
        for(long j = i * i; j < maxn; j += i) {
            isPrime[j] = false; // i 的倍数被标记为合数
        }
    }
    return;
}

struct Factor {
    long x, cnt;
}fac[10];   // 保存质因子

int main()
{
    Initial();  // 初始化质数表
    long n, num = 0;    // num 为不同质因子的个数
    scanf("%ld", &n);
    if(n == 1) {
        printf("1=1");
    }else {
        printf("%ld=", n);
        long sqr = (long)sqrt(n);
        // 枚举根号 n 以内的质因子
        for (int i = 0; i < primes.size() && primes[i] < sqr; i++)
        {
            if(n % primes[i] == 0) {
                fac[num].x = primes[i];
                fac[num].cnt = 0;
                while (n % primes[i] == 0)
                {
                    fac[num].cnt++;
                    n /= primes[i];
                }
                num++;
            }
            if(n == 1)
                break;
        }
        if(n != 1) {
            fac[num].x = n;
            fac[num++].cnt = 1;
        }
        // 按照格式输出
        for (int i = 0; i < num; i++)
        {
            if(i > 0) printf("*");
            printf("%ld", fac[i].x);
            if(fac[i].cnt > 1) {
                printf("^%d", fac[i].cnt);
            }
        }
    }
    
    return 0;
}
Publicado 20 artículos originales · ganado elogios 6 · visitas 991

Supongo que te gusta

Origin blog.csdn.net/weixin_41012699/article/details/105079409
Recomendado
Clasificación